From 5c0a2d4c4e632466371620c98aa4fe127490d779 Mon Sep 17 00:00:00 2001 From: Seopril <49238562+Seopril@users.noreply.github.com> Date: Sat, 16 Jan 2021 17:44:55 -0500 Subject: [PATCH 001/215] Fix YAML export formatting(#1065) (#1150) * Fix YAML export syntax * Fix YAML body block indentation --- features/format.feature | 60 +++++++++++++++++++---------------- jrnl/plugins/yaml_exporter.py | 12 +++++-- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/features/format.feature b/features/format.feature index f5156301..610e3a1e 100644 --- a/features/format.feature +++ b/features/format.feature @@ -410,29 +410,31 @@ Feature: Custom formats """ And the content of file "2020-08-29_entry-the-first.md" in the cache should be """ + --- title: Entry the first. date: 2020-08-29 11:11 starred: False tags: tagone, ipsum, tagtwo + body: | + Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada + quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque + augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu + consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In + commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget + venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. - Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada - quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque - augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu - consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In - commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget - venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. - - Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo - ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse - potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget - molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus - hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis - feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum - urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget - velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac - porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per - conubia nostra, per inceptos himenaeos. + Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo + ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse + potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget + molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus + hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis + feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum + urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget + velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac + porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per + conubia nostra, per inceptos himenaeos. + ... """ Examples: configs @@ -458,21 +460,23 @@ Feature: Custom formats """ And the content of file "2020-09-24_the-third-entry-finally-after-weeks-without-writing.md" in the cache should be """ + --- title: The third entry finally after weeks without writing. date: 2020-09-24 09:14 starred: False tags: tagone, tagthree + body: | + I'm so excited about emojis. 💯 🎶 💩 - I'm so excited about emojis. 💯 🎶 💩 - - Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. - Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla - eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis - dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. - Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis - vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. - Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at - ante eget fringilla. @tagthree and also @tagone + Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. + Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla + eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis + dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. + Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis + vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. + Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at + ante eget fringilla. @tagthree and also @tagone + ... """ Examples: configs diff --git a/jrnl/plugins/yaml_exporter.py b/jrnl/plugins/yaml_exporter.py index df3b0548..7716c6c1 100644 --- a/jrnl/plugins/yaml_exporter.py +++ b/jrnl/plugins/yaml_exporter.py @@ -75,6 +75,11 @@ class YAMLExporter(TextExporter): if previous_line not in ["\r", "\n", "\r\n", "\n\r"]: newbody = newbody + os.linesep + # set indentation for YAML body block + spacebody = "\t" + for line in newbody.splitlines(True): + spacebody = spacebody + "\t" + line + if warn_on_heading_level is True: print( "{}WARNING{}: Headings increased past H6 on export - {} {}".format( @@ -113,14 +118,15 @@ class YAMLExporter(TextExporter): # source directory is entry.journal.config['journal'] # output directory is...? - return "title: {title}\ndate: {date}\nstarred: {starred}\ntags: {tags}\n{dayone} {body} {space}".format( + return "{start}\ntitle: {title}\ndate: {date}\nstarred: {starred}\ntags: {tags}\n{dayone}body: |{body}{end}".format( + start="---", date=date_str, title=entry.title, starred=entry.starred, tags=", ".join([tag[1:] for tag in entry.tags]), dayone=dayone_attributes, - body=newbody, - space="", + body=spacebody, + end="...", ) @classmethod From a6b828e892539fc27271ecf94761bbb9f2a75192 Mon Sep 17 00:00:00 2001 From: Karim Rahal Date: Sun, 17 Jan 2021 00:50:47 +0200 Subject: [PATCH 002/215] Add new date format (`--format date`) for heatmapping (#1146) * Create datecount plugin * Fix plugin import * Update datecount format * Create datecount test * Remove outdated comment * Remove unnecessary datecount export condition * Update test config * Move get_date_counts into DateCountExporter; misc changes * Use --format instead of --export in datecount test * Update datecount test to include configs * Better datecount test * Remove old tests * Change 'datecounts' to 'dates' --- features/format.feature | 19 +++++++++++++++++++ jrnl/plugins/__init__.py | 2 ++ jrnl/plugins/dates_exporter.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 jrnl/plugins/dates_exporter.py diff --git a/features/format.feature b/features/format.feature index 610e3a1e..4981f685 100644 --- a/features/format.feature +++ b/features/format.feature @@ -558,3 +558,22 @@ Feature: Custom formats | basic_encrypted | | basic_folder | | basic_dayone | + + Scenario Outline: Export date counts + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl 2020-08-31 01:01: Hi." + And we run "jrnl --format dates" + Then the output should be + """ + 2020-08-29, 1 + 2020-08-31, 2 + 2020-09-24, 1 + """ + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | diff --git a/jrnl/plugins/__init__.py b/jrnl/plugins/__init__.py index 0d2b39b4..ad174f0b 100644 --- a/jrnl/plugins/__init__.py +++ b/jrnl/plugins/__init__.py @@ -8,6 +8,7 @@ from .jrnl_importer import JRNLImporter from .json_exporter import JSONExporter from .markdown_exporter import MarkdownExporter from .tag_exporter import TagExporter +from .dates_exporter import DatesExporter from .template_exporter import __all__ as template_exporters from .text_exporter import TextExporter from .xml_exporter import XMLExporter @@ -17,6 +18,7 @@ __exporters = [ JSONExporter, MarkdownExporter, TagExporter, + DatesExporter, TextExporter, XMLExporter, YAMLExporter, diff --git a/jrnl/plugins/dates_exporter.py b/jrnl/plugins/dates_exporter.py new file mode 100644 index 00000000..d11e527c --- /dev/null +++ b/jrnl/plugins/dates_exporter.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Copyright (C) 2012-2021 jrnl contributors +# License: https://www.gnu.org/licenses/gpl-3.0.html +from collections import Counter + +from .text_exporter import TextExporter + + +class DatesExporter(TextExporter): + """This Exporter lists dates and their respective counts, for heatingmapping etc.""" + + names = ["dates"] + extension = "dates" + + @classmethod + def export_entry(cls, entry): + raise NotImplementedError + + @classmethod + def export_journal(cls, journal): + """Returns dates and their frequencies for an entire journal.""" + date_counts = Counter() + for entry in journal.entries: + # entry.date.date() gets date without time + date = str(entry.date.date()) + date_counts[date] += 1 + result = "\n".join(f"{date}, {count}" for date, count in date_counts.items()) + return result From 18058c74e51af46576d596c48ef2a4f414026194 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 16 Jan 2021 22:52:40 +0000 Subject: [PATCH 003/215] Update changelog [ci skip] --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b9323db..b32e8e41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,11 +10,13 @@ - Automate Arch deployment [\#1112](https://github.com/jrnl-org/jrnl/issues/1112) - Change temporary file names for better text editor integration [\#1080](https://github.com/jrnl-org/jrnl/issues/1080) - Allow custom file extension for `jrnl --edit` command [\#1059](https://github.com/jrnl-org/jrnl/issues/1059) +- Add new date format \(`--format date`\) for heatmapping [\#1146](https://github.com/jrnl-org/jrnl/pull/1146) ([KarimPwnz](https://github.com/KarimPwnz)) - Allow custom extensions when editing \(for easier syntax highlighting\) [\#1139](https://github.com/jrnl-org/jrnl/pull/1139) ([KarimPwnz](https://github.com/KarimPwnz)) **Fixed bugs:** - Error if password exists in keyring, but retrieval fails for any reason [\#1020](https://github.com/jrnl-org/jrnl/issues/1020) +- Fix YAML export formatting\(\#1065\) [\#1150](https://github.com/jrnl-org/jrnl/pull/1150) ([Seopril](https://github.com/Seopril)) - Fix keyring error handling [\#1138](https://github.com/jrnl-org/jrnl/pull/1138) ([KarimPwnz](https://github.com/KarimPwnz)) - Notify user when config directory can't be created because there is already a file with the same name [\#1134](https://github.com/jrnl-org/jrnl/pull/1134) ([micahellison](https://github.com/micahellison)) From f0e8fa20606688e3c3cdc1ca9aedd9997875ac1a Mon Sep 17 00:00:00 2001 From: Karim Rahal Date: Sun, 17 Jan 2021 00:55:27 +0200 Subject: [PATCH 004/215] Add new `-today-in-history`, `-month`, `-day`, and `-year` search filters (#1145) * Introduce -reminisce, -month, -day, and -year * Update expected_args in parse_args tests * Add check before creating compare_d * Misc changes * Implement testing for -month, -day, -year, and -reminisce * Compress tests into one Scenario Outline * Fix failing tests by updating dates_similar journal * Create 'we set current date and time to' step * Use time.parse in reminisce * Update dates_similar journal * Make 'Searching in a journal' test shorter * Lint * Implement reminiscing test * Add combination tests * Finalize tests * Finalize pytests * Simplify reminisce tests * Change reminsice help (since it also shows today's entries) * Re-do tests; use various tests * Remove old test data * Better scenario description * Standardize format for compare_d * Rename -reminisce to -today-in-history --- features/search.feature | 90 ++++++++++++++++++++++++++++++++++++++++ features/steps/core.py | 21 ++++++++++ jrnl/Journal.py | 11 +++++ jrnl/args.py | 24 +++++++++++ jrnl/jrnl.py | 13 ++++++ tests/test_parse_args.py | 25 +++++++++++ 6 files changed, 184 insertions(+) diff --git a/features/search.feature b/features/search.feature index 9d31bb06..22351b7e 100644 --- a/features/search.feature +++ b/features/search.feature @@ -214,6 +214,96 @@ Feature: Searching in a journal | But I'm better. """ + Scenario Outline: Searching by month + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl -month 9 --short" + Then the output should be "2020-09-24 09:14 The third entry finally after weeks without writing." + And we flush the output + When we run "jrnl -month Sept --short" + Then the output should be "2020-09-24 09:14 The third entry finally after weeks without writing." + And we flush the output + When we run "jrnl -month September --short" + Then the output should be "2020-09-24 09:14 The third entry finally after weeks without writing." + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario Outline: Searching by day + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl -day 31 --short" + Then the output should be "2020-08-31 14:32 A second entry in what I hope to be a long series." + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario Outline: Searching by year + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl 2019-01-01 01:01: I like this year." + And we run "jrnl -year 2019 --short" + Then the output should be "2019-01-01 01:01 I like this year." + And we flush the output + When we run "jrnl -year 19 --short" + Then the output should be "2019-01-01 01:01 I like this year." + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario Outline: Combining month, day, and year search terms + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl -month 08 -day 29 --short" + Then the output should be "2020-08-29 11:11 Entry the first." + And we flush the output + When we run "jrnl -day 29 -year 2020 --short" + Then the output should be "2020-08-29 11:11 Entry the first." + And we flush the output + When we run "jrnl -month 09 -year 2020 --short" + Then the output should be "2020-09-24 09:14 The third entry finally after weeks without writing." + And we flush the output + When we run "jrnl -month 08 -day 29 -year 2020 --short" + Then the output should be "2020-08-29 11:11 Entry the first." + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario Outline: Searching today in history + Given we use the config ".yaml" + And we use the password "test" if prompted + And we set current date and time to "2020-08-31 14:32" + When we run "jrnl 2019-08-31 01:01: Hi, from last year." + And we run "jrnl -today-in-history --short" + Then the output should be + """ + 2019-08-31 01:01 Hi, from last year. + 2020-08-31 14:32 A second entry in what I hope to be a long series. + """ + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + Scenario: Loading a DayOne Journal Given we use the config "dayone.yaml" When we run "jrnl -from 'feb 2013'" diff --git a/features/steps/core.py b/features/steps/core.py index e3af8243..f5215d58 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -17,6 +17,7 @@ import keyring import toml import yaml +import jrnl.time from jrnl import Journal from jrnl import __version__ from jrnl import plugins @@ -159,6 +160,11 @@ def disable_keyring(context): keyring.core.set_keyring(NoKeyring()) +@given('we set current date and time to "{dt}"') +def set_datetime(context, dt): + context.now = dt + + @when('we change directory to "{path}"') def move_up_dir(context, path): os.chdir(path) @@ -197,6 +203,7 @@ def open_editor_and_enter(context, method, text=""): patch("subprocess.call", side_effect=_mock_editor) as mock_editor, \ patch("getpass.getpass", side_effect=_mock_getpass(password)) as mock_getpass, \ patch("sys.stdin.isatty", return_value=True), \ + patch("jrnl.time.parse", side_effect=_mock_time_parse(context)), \ patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ : @@ -289,6 +296,18 @@ def _mock_input(inputs): return prompt_return +def _mock_time_parse(context): + original_parse = jrnl.time.parse + if "now" not in context: + return original_parse + + def wrapper(input, *args, **kwargs): + input = context.now if input == "now" else input + return original_parse(input, *args, **kwargs) + + return wrapper + + @when('we run "{command}" and enter') @when('we run "{command}" and enter nothing') @when('we run "{command}" and enter "{inputs}"') @@ -322,6 +341,7 @@ def run_with_input(context, command, inputs=""): patch("getpass.getpass", side_effect=_mock_getpass(password)) as mock_getpass, \ patch("sys.stdin.read", side_effect=text) as mock_read, \ patch("subprocess.call", side_effect=_mock_editor) as mock_editor, \ + patch("jrnl.time.parse", side_effect=_mock_time_parse(context)), \ patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ : @@ -406,6 +426,7 @@ def run(context, command, text=""): patch("getpass.getpass", side_effect=_mock_getpass(password)) as mock_getpass, \ patch("subprocess.call", side_effect=_mock_editor) as mock_editor, \ patch("sys.stdin.read", side_effect=lambda: text), \ + patch("jrnl.time.parse", side_effect=_mock_time_parse(context)), \ patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ : diff --git a/jrnl/Journal.py b/jrnl/Journal.py index 1871e3c2..4196571d 100644 --- a/jrnl/Journal.py +++ b/jrnl/Journal.py @@ -189,6 +189,9 @@ class Journal: def filter( self, tags=[], + month=None, + day=None, + year=None, start_date=None, end_date=None, starred=False, @@ -220,11 +223,19 @@ class Journal: if contains: contains_lower = contains.casefold() + # Create datetime object for comparison below + # this approach allows various formats + if month or day or year: + compare_d = time.parse(f"{month or 1}.{day or 1}.{year or 1}") + result = [ entry for entry in self.entries if (not tags or tagged(entry.tags)) and (not starred or entry.starred) + and (not month or entry.date.month == compare_d.month) + and (not day or entry.date.day == compare_d.day) + and (not year or entry.date.year == compare_d.year) and (not start_date or entry.date >= start_date) and (not end_date or entry.date <= end_date) and (not exclude or not excluded(entry.tags)) diff --git a/jrnl/args.py b/jrnl/args.py index 5efb00ba..f934ca16 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -176,6 +176,30 @@ def parse_args(args=[]): reading.add_argument( "-on", dest="on_date", metavar="DATE", help="Show entries on this date" ) + reading.add_argument( + "-today-in-history", + dest="today_in_history", + action="store_true", + help="Show entries of today over the years", + ) + reading.add_argument( + "-month", + dest="month", + metavar="DATE", + help="Show entries on this month of any year", + ) + reading.add_argument( + "-day", + dest="day", + metavar="DATE", + help="Show entries on this day of any month", + ) + reading.add_argument( + "-year", + dest="year", + metavar="DATE", + help="Show entries of a specific year", + ) reading.add_argument( "-from", dest="start_date", diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index 415200fa..257358c4 100644 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -15,6 +15,7 @@ from .config import get_config_path from .editor import get_text_from_editor from .editor import get_text_from_stdin from .exception import UserAbort +from . import time def run(args): @@ -77,6 +78,10 @@ def _is_write_mode(args, config, **kwargs): args.edit, args.export, args.end_date, + args.today_in_history, + args.month, + args.day, + args.year, args.limit, args.on_date, args.short, @@ -206,8 +211,16 @@ def _search_journal(args, journal, **kwargs): if args.on_date: args.start_date = args.end_date = args.on_date + if args.today_in_history: + now = time.parse("now") + args.day = now.day + args.month = now.month + journal.filter( tags=args.text, + month=args.month, + day=args.day, + year=args.year, start_date=args.start_date, end_date=args.end_date, strict=args.strict, diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index b9147ac0..252638c9 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -18,6 +18,10 @@ def expected_args(**kwargs): "delete": False, "edit": False, "end_date": None, + "today_in_history": False, + "month": None, + "day": None, + "year": None, "excluded": [], "export": False, "filename": None, @@ -147,6 +151,27 @@ 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) From b6b6e7750ebd1fc26c95d02c9b8ae156840c2c41 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 16 Jan 2021 22:57:15 +0000 Subject: [PATCH 005/215] Update changelog [ci skip] --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b32e8e41..c4360eb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,17 +6,20 @@ **Implemented enhancements:** +- Filter for entries from the same date in previous years [\#1143](https://github.com/jrnl-org/jrnl/issues/1143) - Implement dependency tracker/updater [\#1120](https://github.com/jrnl-org/jrnl/issues/1120) - Automate Arch deployment [\#1112](https://github.com/jrnl-org/jrnl/issues/1112) - Change temporary file names for better text editor integration [\#1080](https://github.com/jrnl-org/jrnl/issues/1080) - Allow custom file extension for `jrnl --edit` command [\#1059](https://github.com/jrnl-org/jrnl/issues/1059) - Add new date format \(`--format date`\) for heatmapping [\#1146](https://github.com/jrnl-org/jrnl/pull/1146) ([KarimPwnz](https://github.com/KarimPwnz)) +- Add new `-today-in-history`, `-month`, `-day`, and `-year` search filters [\#1145](https://github.com/jrnl-org/jrnl/pull/1145) ([KarimPwnz](https://github.com/KarimPwnz)) - Allow custom extensions when editing \(for easier syntax highlighting\) [\#1139](https://github.com/jrnl-org/jrnl/pull/1139) ([KarimPwnz](https://github.com/KarimPwnz)) **Fixed bugs:** +- YAML Export lacking delimiters [\#1065](https://github.com/jrnl-org/jrnl/issues/1065) - Error if password exists in keyring, but retrieval fails for any reason [\#1020](https://github.com/jrnl-org/jrnl/issues/1020) -- Fix YAML export formatting\(\#1065\) [\#1150](https://github.com/jrnl-org/jrnl/pull/1150) ([Seopril](https://github.com/Seopril)) +- Add delimiters in YAML format [\#1150](https://github.com/jrnl-org/jrnl/pull/1150) ([Seopril](https://github.com/Seopril)) - Fix keyring error handling [\#1138](https://github.com/jrnl-org/jrnl/pull/1138) ([KarimPwnz](https://github.com/KarimPwnz)) - Notify user when config directory can't be created because there is already a file with the same name [\#1134](https://github.com/jrnl-org/jrnl/pull/1134) ([micahellison](https://github.com/micahellison)) From 9e6cd8820f3e7ff426bafd27d9ae955806404425 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 16 Jan 2021 15:19:11 -0800 Subject: [PATCH 006/215] Fix OS compatibility issues for editors with spaces, slashes, and quotes (#1153) * Fix inverted POSIX check, refactor os_compat, and add tests for it * Fix missing parentheses and remove skip_win on test that is passing in Windows now * Fix expected quotes in quoted args * Make output clearer on failing test * Bringing skip_win back to test whose failure is a bit more complicated than expected --- features/environment.py | 4 +- features/steps/core.py | 11 ++--- features/steps/export_steps.py | 17 +++++-- jrnl/color.py | 2 +- jrnl/editor.py | 6 +-- jrnl/os_compat.py | 14 +++++- tests/test_os_compat.py | 87 ++++++++++++++++++++++++++++++++++ 7 files changed, 121 insertions(+), 20 deletions(-) create mode 100644 tests/test_os_compat.py diff --git a/features/environment.py b/features/environment.py index 71ed8969..f4baab34 100644 --- a/features/environment.py +++ b/features/environment.py @@ -42,7 +42,7 @@ def before_feature(context, feature): feature.skip() return - if "skip_win" in feature.tags and on_windows: + if "skip_win" in feature.tags and on_windows(): feature.skip("Skipping on Windows") return @@ -69,7 +69,7 @@ def before_scenario(context, scenario): scenario.skip() return - if "skip_win" in scenario.effective_tags and on_windows: + if "skip_win" in scenario.effective_tags and on_windows(): scenario.skip("Skipping on Windows") return diff --git a/features/steps/core.py b/features/steps/core.py index f5215d58..abac4917 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -6,7 +6,6 @@ from collections import defaultdict import os from pathlib import Path import re -import shlex import time from unittest.mock import patch @@ -23,7 +22,7 @@ from jrnl import __version__ from jrnl import plugins from jrnl.cli import cli from jrnl.config import load_config -from jrnl.os_compat import on_windows +from jrnl.os_compat import split_args try: import parsedatetime.parsedatetime_consts as pdt @@ -88,10 +87,6 @@ class FailedKeyring(keyring.backend.KeyringBackend): keyring.set_keyring(TestKeyring()) -def ushlex(command): - return shlex.split(command, posix=not on_windows) - - def read_journal(context, journal_name="default"): configuration = load_config(context.config_path) with open(configuration["journals"][journal_name]) as journal_file: @@ -319,7 +314,7 @@ def run_with_input(context, command, inputs=""): else: text = iter([inputs]) - args = ushlex(command)[1:] + args = split_args(command)[1:] def _mock_editor(command): context.editor_command = command @@ -403,7 +398,7 @@ def run(context, command, text=""): cache_dir = os.path.join("features", "cache", context.cache_dir) command = command.format(cache_dir=cache_dir) - args = ushlex(command) + args = split_args(command) def _mock_editor(command): context.editor_command = command diff --git a/features/steps/export_steps.py b/features/steps/export_steps.py index 6a5c8e46..f885591c 100644 --- a/features/steps/export_steps.py +++ b/features/steps/export_steps.py @@ -169,17 +169,24 @@ def assert_exported_yaml_file_content(context, file_path, cache_dir=None): for actual_line, expected_line in zip(actual_content, expected_content): if actual_line.startswith("tags: ") and expected_line.startswith("tags: "): - assert_equal_tags_ignoring_order(actual_line, expected_line) + assert_equal_tags_ignoring_order( + actual_line, expected_line, actual_content, expected_content + ) else: assert actual_line.strip() == expected_line.strip(), [ - actual_line.strip(), - expected_line.strip(), + [actual_line.strip(), expected_line.strip()], + [actual_content, expected_content], ] -def assert_equal_tags_ignoring_order(actual_line, expected_line): +def assert_equal_tags_ignoring_order( + actual_line, expected_line, actual_content, expected_content +): actual_tags = set(tag.strip() for tag in actual_line[len("tags: ") :].split(",")) expected_tags = set( tag.strip() for tag in expected_line[len("tags: ") :].split(",") ) - assert actual_tags == expected_tags, [actual_tags, expected_tags] + assert actual_tags == expected_tags, [ + [actual_tags, expected_tags], + [expected_content, actual_content], + ] diff --git a/jrnl/color.py b/jrnl/color.py index dca28117..3bdd4149 100644 --- a/jrnl/color.py +++ b/jrnl/color.py @@ -7,7 +7,7 @@ import colorama from .os_compat import on_windows -if on_windows: +if on_windows(): colorama.init() WARNING_COLOR = colorama.Fore.YELLOW diff --git a/jrnl/editor.py b/jrnl/editor.py index 1a68028d..086d84db 100644 --- a/jrnl/editor.py +++ b/jrnl/editor.py @@ -1,6 +1,5 @@ import logging import os -import shlex import subprocess import sys import tempfile @@ -10,6 +9,7 @@ from pathlib import Path from .color import ERROR_COLOR from .color import RESET_COLOR from .os_compat import on_windows +from .os_compat import split_args def get_text_from_editor(config, template=""): @@ -25,7 +25,7 @@ def get_text_from_editor(config, template=""): f.write(template) try: - subprocess.call(shlex.split(config["editor"], posix=on_windows) + [tmpfile]) + subprocess.call(split_args(config["editor"]) + [tmpfile]) except Exception as e: error_msg = f""" {ERROR_COLOR}{str(e)}{RESET_COLOR} @@ -47,7 +47,7 @@ def get_text_from_editor(config, template=""): def get_text_from_stdin(): - _how_to_quit = "Ctrl+z and then Enter" if on_windows else "Ctrl+d" + _how_to_quit = "Ctrl+z and then Enter" if on_windows() else "Ctrl+d" print( f"[Writing Entry; on a blank line, press {_how_to_quit} to finish writing]\n", file=sys.stderr, diff --git a/jrnl/os_compat.py b/jrnl/os_compat.py index b38d9d60..6615b886 100644 --- a/jrnl/os_compat.py +++ b/jrnl/os_compat.py @@ -1,6 +1,18 @@ # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html +import shlex from sys import platform -on_windows = "win32" in platform + +def on_windows(): + return "win32" in platform + + +def on_posix(): + return not on_windows() + + +def split_args(args): + """Split arguments and add escape characters as appropriate for the OS""" + return shlex.split(args, posix=on_posix()) diff --git a/tests/test_os_compat.py b/tests/test_os_compat.py new file mode 100644 index 00000000..f7c058f1 --- /dev/null +++ b/tests/test_os_compat.py @@ -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 From b117c7a2601a09206b7d62dc9fd8e1b3d3b7c286 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 16 Jan 2021 23:20:59 +0000 Subject: [PATCH 007/215] Increment version to v2.7-beta --- jrnl/__version__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jrnl/__version__.py b/jrnl/__version__.py index fc38b65a..b9dc436f 100644 --- a/jrnl/__version__.py +++ b/jrnl/__version__.py @@ -1 +1 @@ -__version__ = "v2.6" +__version__ = "v2.7-beta" diff --git a/pyproject.toml b/pyproject.toml index c03a4f88..0bf1460e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "jrnl" -version = "v2.6" +version = "v2.7-beta" description = "Collect your thoughts and notes without leaving the command line." authors = [ "jrnl contributors ", From 2e254d55fb2b27067760f7733b6d344d60a529c2 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 16 Jan 2021 23:22:56 +0000 Subject: [PATCH 008/215] Update changelog [ci skip] --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4360eb8..7999a69f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ # Changelog -## [Unreleased](https://github.com/jrnl-org/jrnl/) +## [v2.7-beta](https://pypi.org/project/jrnl/v2.7-beta/) (2021-01-16) -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.6...HEAD) +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.6...v2.7-beta) **Implemented enhancements:** @@ -17,8 +17,10 @@ **Fixed bugs:** +- `shlex.split` usage for editor config with commands that have spaces [\#1151](https://github.com/jrnl-org/jrnl/issues/1151) - YAML Export lacking delimiters [\#1065](https://github.com/jrnl-org/jrnl/issues/1065) - Error if password exists in keyring, but retrieval fails for any reason [\#1020](https://github.com/jrnl-org/jrnl/issues/1020) +- Fix OS compatibility issues for editors with spaces, slashes, and quotes [\#1153](https://github.com/jrnl-org/jrnl/pull/1153) ([micahellison](https://github.com/micahellison)) - Add delimiters in YAML format [\#1150](https://github.com/jrnl-org/jrnl/pull/1150) ([Seopril](https://github.com/Seopril)) - Fix keyring error handling [\#1138](https://github.com/jrnl-org/jrnl/pull/1138) ([KarimPwnz](https://github.com/KarimPwnz)) - Notify user when config directory can't be created because there is already a file with the same name [\#1134](https://github.com/jrnl-org/jrnl/pull/1134) ([micahellison](https://github.com/micahellison)) From c06b5cf297d64a2424e8c94e64a6f18dc9f96978 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 16 Jan 2021 17:40:09 -0800 Subject: [PATCH 009/215] Fix homebrew release, add options for relase pipeline (#1154) --- .github/workflows/release.yaml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 884a8c48..b3ac7dbe 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -5,6 +5,18 @@ on: version: description: 'Version (e.g. v2.5, v2.5.1-beta, v2.6-beta2)' required: true + include_repo_version: + description: 'Update version in repo? (yes/no)' + require: true + default: yes + include_pypi: + description: 'Publish to PyPI? (yes/no)' + required: true + default: yes + include_brew: + description: 'Publish to Homebrew? (yes/no)' + required: true + default: yes jobs: validate: @@ -65,12 +77,13 @@ jobs: run: pip install poetry - name: Update version in files + if: {{ github.event.inputs.include_repo_version == 'yes' }} run: | poetry version "$JRNL_VERSION" echo __version__ = \"$JRNL_VERSION\" > jrnl/__version__.py - name: Commit updated files - if: ${{ github.repository == env.HOME_REPO }} + if: ${{ github.event.inputs.include_repo_version == 'yes' && github.repository == env.HOME_REPO }} run: | git add pyproject.toml jrnl/__version__.py git commit -m "Increment version to ${JRNL_VERSION}" @@ -82,7 +95,7 @@ jobs: run: poetry build - name: Deploy to PyPI - if: ${{ github.repository == env.HOME_REPO }} + if: ${{ github.event.inputs.include_pypi == 'yes' && github.repository == env.HOME_REPO }} env: POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }} run: poetry publish @@ -94,6 +107,7 @@ jobs: echo "::set-output name=pypi_version::$pypi_version" release_homebrew: + if: ${{ github.event.inputs.include_brew == 'yes' }} needs: release_pypi name: "Release to Homebrew" runs-on: macos-latest @@ -155,6 +169,7 @@ jobs: BRANCH_NAME="jrnl-${JRNL_VERSION}--${RANDOM}" git remote rename origin upstream git remote add origin "https://github.com/${BOT_REPO}.git" + git fetch --unshallow upstream git fetch origin git checkout -b $BRANCH_NAME git push -u origin $BRANCH_NAME From 99d01985302ecb6ceb0255ec1509d332d6a04667 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sun, 17 Jan 2021 01:42:03 +0000 Subject: [PATCH 010/215] Update changelog [ci skip] --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7999a69f..f2110f8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [Unreleased](https://github.com/jrnl-org/jrnl/) + +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7-beta...HEAD) + +**Build:** + +- Fix homebrew release, add options for release pipeline [\#1154](https://github.com/jrnl-org/jrnl/pull/1154) ([wren](https://github.com/wren)) + ## [v2.7-beta](https://pypi.org/project/jrnl/v2.7-beta/) (2021-01-16) [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.6...v2.7-beta) From f80f033d5d9c9ba593d0375c3ee6d76074fd4139 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sun, 17 Jan 2021 10:51:22 -0800 Subject: [PATCH 011/215] fix typos --- .github/workflows/release.yaml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index b3ac7dbe..3d57918a 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -6,17 +6,17 @@ on: description: 'Version (e.g. v2.5, v2.5.1-beta, v2.6-beta2)' required: true include_repo_version: - description: 'Update version in repo? (yes/no)' + description: 'Update version in repo? (true/false)' require: true - default: yes + default: true include_pypi: - description: 'Publish to PyPI? (yes/no)' + description: 'Publish to PyPI? (true/false)' required: true - default: yes + default: true include_brew: - description: 'Publish to Homebrew? (yes/no)' + description: 'Publish to Homebrew? (true/false)' required: true - default: yes + default: true jobs: validate: @@ -77,13 +77,13 @@ jobs: run: pip install poetry - name: Update version in files - if: {{ github.event.inputs.include_repo_version == 'yes' }} + if: ${{ github.event.inputs.include_repo_version == 'true' }} run: | poetry version "$JRNL_VERSION" echo __version__ = \"$JRNL_VERSION\" > jrnl/__version__.py - name: Commit updated files - if: ${{ github.event.inputs.include_repo_version == 'yes' && github.repository == env.HOME_REPO }} + if: ${{ github.event.inputs.include_repo_version == 'true' && github.repository == env.HOME_REPO }} run: | git add pyproject.toml jrnl/__version__.py git commit -m "Increment version to ${JRNL_VERSION}" @@ -95,7 +95,7 @@ jobs: run: poetry build - name: Deploy to PyPI - if: ${{ github.event.inputs.include_pypi == 'yes' && github.repository == env.HOME_REPO }} + if: ${{ github.event.inputs.include_pypi == 'true' && github.repository == env.HOME_REPO }} env: POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }} run: poetry publish @@ -107,7 +107,7 @@ jobs: echo "::set-output name=pypi_version::$pypi_version" release_homebrew: - if: ${{ github.event.inputs.include_brew == 'yes' }} + if: ${{ github.event.inputs.include_brew == 'true' }} needs: release_pypi name: "Release to Homebrew" runs-on: macos-latest From ea7357ca26c611c18383b11ce325aee5cfd2547a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 23 Jan 2021 13:27:54 -0800 Subject: [PATCH 012/215] Bump pyyaml from 5.3.1 to 5.4.1 (#1158) Bumps [pyyaml](https://github.com/yaml/pyyaml) from 5.3.1 to 5.4.1. - [Release notes](https://github.com/yaml/pyyaml/releases) - [Changelog](https://github.com/yaml/pyyaml/blob/master/CHANGES) - [Commits](https://github.com/yaml/pyyaml/compare/5.3.1...5.4.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/poetry.lock b/poetry.lock index fc0f5895..abb802cb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -481,11 +481,11 @@ python-versions = "*" [[package]] name = "pyyaml" -version = "5.3.1" +version = "5.4.1" description = "YAML parser and emitter for Python" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [[package]] name = "regex" @@ -855,19 +855,27 @@ pyxdg = [ {file = "pyxdg-0.27.tar.gz", hash = "sha256:80bd93aae5ed82435f20462ea0208fb198d8eec262e831ee06ce9ddb6b91c5a5"}, ] pyyaml = [ - {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, - {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, - {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, - {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, - {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, - {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, - {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, - {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, - {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, - {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, - {file = "PyYAML-5.3.1-cp39-cp39-win32.whl", hash = "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a"}, - {file = "PyYAML-5.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e"}, - {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, + {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, + {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, + {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, + {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, + {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, + {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, + {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, + {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, + {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, + {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, + {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, ] regex = [ {file = "regex-2020.11.13-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8b882a78c320478b12ff024e81dc7d43c1462aa4a3341c754ee65d857a521f85"}, From b53578262182788d0a5c4e43584babdd5238ccbc Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 23 Jan 2021 21:29:43 +0000 Subject: [PATCH 013/215] Update changelog [ci skip] --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2110f8b..bf2bb051 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,18 @@ [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7-beta...HEAD) +**Fixed bugs:** + +- Editor can't be launched on Windows when using full path to editor executable [\#1096](https://github.com/jrnl-org/jrnl/issues/1096) + **Build:** - Fix homebrew release, add options for release pipeline [\#1154](https://github.com/jrnl-org/jrnl/pull/1154) ([wren](https://github.com/wren)) +**Packaging:** + +- Bump pyyaml from 5.3.1 to 5.4.1 [\#1158](https://github.com/jrnl-org/jrnl/pull/1158) ([dependabot[bot]](https://github.com/apps/dependabot)) + ## [v2.7-beta](https://pypi.org/project/jrnl/v2.7-beta/) (2021-01-16) [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.6...v2.7-beta) From 897943857dde82d53d8d12cd2649e66c1a09158e Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 23 Jan 2021 13:35:32 -0800 Subject: [PATCH 014/215] Simplify VS Code documentation for all platforms and add note about PATH variable (#1160) --- docs/recipes.md | 47 ++++++++++++++++++----------------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/docs/recipes.md b/docs/recipes.md index b7d370a4..14e08e14 100644 --- a/docs/recipes.md +++ b/docs/recipes.md @@ -162,10 +162,13 @@ in your `jrnl.yaml` file. (See [advanced usage](./advanced.md) for details). !!! note To save and log any entry edits, save and close the file. +If your editor is not in your operating system's `PATH` environment variable, +then you will have to enter in the full path of your editor. + ### Sublime Text -To use Sublime Text, install the command line tools for Sublime Text and -configure your `jrnl.yaml` like this: +To use [Sublime Text](https://www.sublimetext.com/), install the command line +tools for Sublime Text and configure your `jrnl.yaml` like this: ```yaml editor: "subl -w" @@ -174,9 +177,21 @@ editor: "subl -w" Note the `-w` flag to make sure jrnl waits for Sublime Text to close the file before writing into the journal. +### Visual Studio Code + +[Visual Studio Code](https://code.visualstudio.com) also requires a flag +that tells the process to wait until the file is closed before exiting: + +```yaml +editor: "code --wait" +``` + +On Windows, `code` is not added to the path by default, so you'll need to +enter the full path to your `code.exe` file, or add it to the `PATH` variable. + ### MacVim -Similar to Sublime Text, MacVim must be started with a flag that tells +Also similar to Sublime Text, MacVim must be started with a flag that tells the the process to wait until the file is closed before passing control back to journal. In the case of MacVim, this is `-f`: @@ -219,29 +234,3 @@ editor: "C:\\Program Files (x86)\\Notepad++\\notepad++.exe -multiInst -nosession The double backslashes are needed so jrnl can read the file path correctly. The `-multiInst -nosession` options will cause jrnl to open its own Notepad++ window. - -### Visual Studio Code - -To set [Visual Studo Code](https://code.visualstudio.com) as your editor on Linux, edit `jrnl.yaml` like this: - -```yaml -editor: "/usr/bin/code --wait" -``` - -The `--wait` argument tells VS Code to wait for files to be written out before handing back control to jrnl. - -On MacOS you will need to add VS Code to your PATH. You can do that by adding: - -```sh -export PATH="\$PATH:/Applications/Visual Studio Code.app/Contents/Resources/app/bin" -``` - -to your `.bash_profile`, or by running the **Install 'code' command in PATH** command from the command pallet in VS Code. - -Then you can add: - -```yaml -editor: "code --wait" -``` - -to `jrnl.yaml`. See also the [Visual Studio Code documentation](https://code.visualstudio.com/docs/setup/mac) From 9f386163a42ceb6450bf5e01c782ccf8370d3180 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 23 Jan 2021 21:37:04 +0000 Subject: [PATCH 015/215] Update changelog [ci skip] --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf2bb051..1dfcd423 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,11 @@ - Fix homebrew release, add options for release pipeline [\#1154](https://github.com/jrnl-org/jrnl/pull/1154) ([wren](https://github.com/wren)) +**Documentation:** + +- add instructions to add VSCode as an external editor for Windows [\#1155](https://github.com/jrnl-org/jrnl/issues/1155) +- Clarify editor documentation for PATH variable and VS Code [\#1160](https://github.com/jrnl-org/jrnl/pull/1160) ([micahellison](https://github.com/micahellison)) + **Packaging:** - Bump pyyaml from 5.3.1 to 5.4.1 [\#1158](https://github.com/jrnl-org/jrnl/pull/1158) ([dependabot[bot]](https://github.com/apps/dependabot)) From a32070b08a640e18033a57cbfb548b75b138b20d Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 23 Jan 2021 22:49:45 +0000 Subject: [PATCH 016/215] Increment version to v2.7 --- jrnl/__version__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jrnl/__version__.py b/jrnl/__version__.py index b9dc436f..57da66a0 100644 --- a/jrnl/__version__.py +++ b/jrnl/__version__.py @@ -1 +1 @@ -__version__ = "v2.7-beta" +__version__ = "v2.7" diff --git a/pyproject.toml b/pyproject.toml index 0bf1460e..e47f27f7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "jrnl" -version = "v2.7-beta" +version = "v2.7" description = "Collect your thoughts and notes without leaving the command line." authors = [ "jrnl contributors ", From ef563c807f9a4b84e0aedcf48e425a220b91d8e4 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 23 Jan 2021 22:51:22 +0000 Subject: [PATCH 017/215] Update changelog [ci skip] --- CHANGELOG.md | 39 +++++++-------------------------------- 1 file changed, 7 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dfcd423..72eb0379 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,46 +1,18 @@ # Changelog -## [Unreleased](https://github.com/jrnl-org/jrnl/) +## [v2.7](https://pypi.org/project/jrnl/v2.7/) (2021-01-23) -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7-beta...HEAD) - -**Fixed bugs:** - -- Editor can't be launched on Windows when using full path to editor executable [\#1096](https://github.com/jrnl-org/jrnl/issues/1096) - -**Build:** - -- Fix homebrew release, add options for release pipeline [\#1154](https://github.com/jrnl-org/jrnl/pull/1154) ([wren](https://github.com/wren)) - -**Documentation:** - -- add instructions to add VSCode as an external editor for Windows [\#1155](https://github.com/jrnl-org/jrnl/issues/1155) -- Clarify editor documentation for PATH variable and VS Code [\#1160](https://github.com/jrnl-org/jrnl/pull/1160) ([micahellison](https://github.com/micahellison)) - -**Packaging:** - -- Bump pyyaml from 5.3.1 to 5.4.1 [\#1158](https://github.com/jrnl-org/jrnl/pull/1158) ([dependabot[bot]](https://github.com/apps/dependabot)) - -## [v2.7-beta](https://pypi.org/project/jrnl/v2.7-beta/) (2021-01-16) - -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.6...v2.7-beta) +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7-beta...v2.7) **Implemented enhancements:** -- Filter for entries from the same date in previous years [\#1143](https://github.com/jrnl-org/jrnl/issues/1143) -- Implement dependency tracker/updater [\#1120](https://github.com/jrnl-org/jrnl/issues/1120) -- Automate Arch deployment [\#1112](https://github.com/jrnl-org/jrnl/issues/1112) -- Change temporary file names for better text editor integration [\#1080](https://github.com/jrnl-org/jrnl/issues/1080) -- Allow custom file extension for `jrnl --edit` command [\#1059](https://github.com/jrnl-org/jrnl/issues/1059) - Add new date format \(`--format date`\) for heatmapping [\#1146](https://github.com/jrnl-org/jrnl/pull/1146) ([KarimPwnz](https://github.com/KarimPwnz)) - Add new `-today-in-history`, `-month`, `-day`, and `-year` search filters [\#1145](https://github.com/jrnl-org/jrnl/pull/1145) ([KarimPwnz](https://github.com/KarimPwnz)) - Allow custom extensions when editing \(for easier syntax highlighting\) [\#1139](https://github.com/jrnl-org/jrnl/pull/1139) ([KarimPwnz](https://github.com/KarimPwnz)) **Fixed bugs:** -- `shlex.split` usage for editor config with commands that have spaces [\#1151](https://github.com/jrnl-org/jrnl/issues/1151) -- YAML Export lacking delimiters [\#1065](https://github.com/jrnl-org/jrnl/issues/1065) -- Error if password exists in keyring, but retrieval fails for any reason [\#1020](https://github.com/jrnl-org/jrnl/issues/1020) +- Editor can't be launched on Windows when using full path to editor executable [\#1096](https://github.com/jrnl-org/jrnl/issues/1096) - Fix OS compatibility issues for editors with spaces, slashes, and quotes [\#1153](https://github.com/jrnl-org/jrnl/pull/1153) ([micahellison](https://github.com/micahellison)) - Add delimiters in YAML format [\#1150](https://github.com/jrnl-org/jrnl/pull/1150) ([Seopril](https://github.com/Seopril)) - Fix keyring error handling [\#1138](https://github.com/jrnl-org/jrnl/pull/1138) ([KarimPwnz](https://github.com/KarimPwnz)) @@ -48,11 +20,13 @@ **Build:** +- Fix homebrew release, add options for release pipeline [\#1154](https://github.com/jrnl-org/jrnl/pull/1154) ([wren](https://github.com/wren)) - Fix changelog generator [\#1127](https://github.com/jrnl-org/jrnl/pull/1127) ([wren](https://github.com/wren)) **Documentation:** -- Clarify installation docs [\#1097](https://github.com/jrnl-org/jrnl/issues/1097) +- add instructions to add VSCode as an external editor for Windows [\#1155](https://github.com/jrnl-org/jrnl/issues/1155) +- Clarify editor documentation for PATH variable and VS Code [\#1160](https://github.com/jrnl-org/jrnl/pull/1160) ([micahellison](https://github.com/micahellison)) - Emphasize installing dependencies before testing [\#1148](https://github.com/jrnl-org/jrnl/pull/1148) ([gumatias](https://github.com/gumatias)) - Clarify installation documentation \(\#1097\) [\#1137](https://github.com/jrnl-org/jrnl/pull/1137) ([Seopril](https://github.com/Seopril)) - Fix broken search bar in docs site [\#1135](https://github.com/jrnl-org/jrnl/pull/1135) ([wren](https://github.com/wren)) @@ -62,6 +36,7 @@ **Packaging:** +- Bump pyyaml from 5.3.1 to 5.4.1 [\#1158](https://github.com/jrnl-org/jrnl/pull/1158) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump keyring from 21.7.0 to 21.8.0 [\#1136](https://github.com/jrnl-org/jrnl/pull/1136) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump pytz from 2020.4 to 2020.5 [\#1130](https://github.com/jrnl-org/jrnl/pull/1130) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Bump pytest from 6.2.0 to 6.2.1 [\#1129](https://github.com/jrnl-org/jrnl/pull/1129) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) From 8a78c349175da90c7c79e3bec81698a6b910b821 Mon Sep 17 00:00:00 2001 From: eshrh <16175276+eshrh@users.noreply.github.com> Date: Sat, 23 Jan 2021 18:29:43 -0500 Subject: [PATCH 018/215] Support title splitting for fullwidth CJK terminals (#1163) * Split by fullwidth terminals without spaces. * Add test * Update write.feature --- features/write.feature | 14 ++++++++++++++ jrnl/Entry.py | 13 ++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/features/write.feature b/features/write.feature index efa26201..eb22e480 100644 --- a/features/write.feature +++ b/features/write.feature @@ -28,6 +28,20 @@ Feature: Writing new entries. | basic_folder | | basic_dayone | + Scenario Outline: CJK entry should be split at fullwidth period without following space. + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl 七転び。八起き" + And we run "jrnl -1" + Then the output should contain "| 八起き" + + Examples: configs + | config_file | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + Scenario Outline: Writing an entry from command line should store the entry Given we use the config ".yaml" And we use the password "bad doggie no biscuit" if prompted diff --git a/jrnl/Entry.py b/jrnl/Entry.py index 2a85e015..67ba84f3 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -204,14 +204,17 @@ class Entry: # https://github.com/fnl/segtok SENTENCE_SPLITTER = re.compile( r""" -( # A sentence ends at one of two sequences: - [.!?\u2026\u203C\u203D\u2047\u2048\u2049\u22EF\u3002\uFE52\uFE57\uFF01\uFF0E\uFF1F\uFF61] # Either, a sequence starting with a sentence terminal, + ( + [.!?\u2026\u203C\u203D\u2047\u2048\u2049\u22EF\uFE52\uFE57] # Sequence starting with a sentence terminal, [\'\u2019\"\u201D]? # an optional right quote, - [\]\)]* # optional closing brackets and - \s+ # a sequence of required spaces. -)""", + [\]\)]* # optional closing bracket + \s+ # AND a sequence of required spaces. + ) + |[\uFF01\uFF0E\uFF1F\uFF61\u3002] # CJK full/half width terminals usually do not have following spaces. + """, re.VERBOSE, ) + SENTENCE_SPLITTER_ONLY_NEWLINE = re.compile("\n") From bd1c5c3f624b7bcebb23ad91f76218572727a585 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 30 Jan 2021 13:31:24 -0800 Subject: [PATCH 019/215] Add brew and gitter badges to README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index bc295f6c..55202436 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ jrnl [![Testing](https://github.com/jrnl-org/jrnl/workflows/Testing/badge.svg)](https://github.com/jrnl-org/jrnl/actions?query=workflow%3ATesting) [![Downloads](https://pepy.tech/badge/jrnl)](https://pepy.tech/project/jrnl) [![Version](http://img.shields.io/pypi/v/jrnl.svg?style=flat)](https://pypi.python.org/pypi/jrnl/) + [![Homebrew](https://img.shields.io/homebrew/v/jrnl?style=flat-square)](https://formulae.brew.sh/formula/jrnl) + [![Gitter](https://img.shields.io/gitter/room/jrnl-org/jrnl)](https://gitter.im/jrnl-org/jrnl) ==== _To get help, [submit an issue](https://github.com/jrnl-org/jrnl/issues/new/choose) on From ac0c49918d1c4ec9ec6639f7ab43f408e3cc6dd3 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 30 Jan 2021 21:34:06 +0000 Subject: [PATCH 020/215] Update changelog [ci skip] --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72eb0379..a3ba6eca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [Unreleased](https://github.com/jrnl-org/jrnl/) + +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7...HEAD) + +**Implemented enhancements:** + +- Allow timestamps in command line for new entries with editor [\#1083](https://github.com/jrnl-org/jrnl/issues/1083) + ## [v2.7](https://pypi.org/project/jrnl/v2.7/) (2021-01-23) [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7-beta...v2.7) From ea845a84088a89d9d59605aef80629512557ec14 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 30 Jan 2021 13:47:26 -0800 Subject: [PATCH 021/215] Make journal selection behavior more consistent when there's a colon with no date (#1164) --- features/multiple_journals.feature | 14 ++++++++++++++ jrnl/config.py | 16 ++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/features/multiple_journals.feature b/features/multiple_journals.feature index 6a9efe78..222be100 100644 --- a/features/multiple_journals.feature +++ b/features/multiple_journals.feature @@ -29,6 +29,20 @@ Feature: Multiple journals And journal "work" should have 1 entry And journal "work" should contain "2012-07-23" + Scenario: Write to specified journal without a timestamp but with colon + Given we use the config "multiple.yaml" + When we run "jrnl work : a long day in the office" + Then journal "default" should have 2 entries + And journal "work" should have 1 entry + And journal "work" should contain "a long day in the office" + + Scenario: Write to specified journal without a timestamp but with colon + Given we use the config "multiple.yaml" + When we run "jrnl work: a long day in the office" + Then journal "default" should have 2 entries + And journal "work" should have 1 entry + And journal "work" should contain "a long day in the office" + Scenario: Create new journals as required Given we use the config "multiple.yaml" Then journal "ideas" should not exist diff --git a/jrnl/config.py b/jrnl/config.py index 9e57de3d..a5a1d1cc 100644 --- a/jrnl/config.py +++ b/jrnl/config.py @@ -138,10 +138,18 @@ def update_config(config, new_config, scope, force_local=False): def get_journal_name(args, config): args.journal_name = DEFAULT_JOURNAL_KEY - if args.text and args.text[0] in config["journals"]: - args.journal_name = args.text[0] - args.text = args.text[1:] - elif DEFAULT_JOURNAL_KEY not in config["journals"]: + + # The first arg might be a journal name + if args.text: + potential_journal_name = args.text[0] + if potential_journal_name[-1] == ":": + potential_journal_name = potential_journal_name[0:-1] + + if potential_journal_name in config["journals"]: + args.journal_name = potential_journal_name + args.text = args.text[1:] + + if args.journal_name not in config["journals"]: print("No default journal configured.", file=sys.stderr) print(list_journals(config), file=sys.stderr) sys.exit(1) From fbb40b75f6dd754be2a477a259d4ceba124699ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 30 Jan 2021 13:47:37 -0800 Subject: [PATCH 022/215] Bump pytest from 6.2.1 to 6.2.2 (#1167) Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.2.1 to 6.2.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/6.2.1...6.2.2) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index abb802cb..6e8193dc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -424,7 +424,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "pytest" -version = "6.2.1" +version = "6.2.2" description = "pytest: simple powerful testing with Python" category = "dev" optional = false @@ -835,8 +835,8 @@ pyparsing = [ {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pytest = [ - {file = "pytest-6.2.1-py3-none-any.whl", hash = "sha256:1969f797a1a0dbd8ccf0fecc80262312729afea9c17f1d70ebf85c5e76c6f7c8"}, - {file = "pytest-6.2.1.tar.gz", hash = "sha256:66e419b1899bc27346cb2c993e12c5e5e8daba9073c1fbce33b9807abc95c306"}, + {file = "pytest-6.2.2-py3-none-any.whl", hash = "sha256:b574b57423e818210672e07ca1fa90aaf194a4f63f3ab909a2c67ebb22913839"}, + {file = "pytest-6.2.2.tar.gz", hash = "sha256:9d1edf9e7d0b84d72ea3dbcdfd22b35fb543a5e8f2a60092dd578936bf63d7f9"}, ] python-dateutil = [ {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, From 6e28b0b4a124e51212a640d310c4ad1f700335bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 30 Jan 2021 13:48:08 -0800 Subject: [PATCH 023/215] Bump keyring from 21.8.0 to 22.0.1 (#1168) Bumps [keyring](https://github.com/jaraco/keyring) from 21.8.0 to 22.0.1. - [Release notes](https://github.com/jaraco/keyring/releases) - [Changelog](https://github.com/jaraco/keyring/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/keyring/compare/v21.8.0...v22.0.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 6e8193dc..50135423 100644 --- a/poetry.lock +++ b/poetry.lock @@ -212,7 +212,7 @@ python-versions = ">=3.6" [[package]] name = "keyring" -version = "21.8.0" +version = "22.0.1" description = "Store and access your passwords safely." category = "main" optional = false @@ -226,7 +226,7 @@ SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "pytest-black (>=0.3.7)", "pytest-mypy"] +testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "pytest-black (>=0.3.7)", "pytest-mypy"] [[package]] name = "livereload" @@ -735,8 +735,8 @@ joblib = [ {file = "joblib-0.17.0.tar.gz", hash = "sha256:9e284edd6be6b71883a63c9b7f124738a3c16195513ad940eae7e3438de885d5"}, ] keyring = [ - {file = "keyring-21.8.0-py3-none-any.whl", hash = "sha256:4be9cbaaaf83e61d6399f733d113ede7d1c73bc75cb6aeb64eee0f6ac39b30ea"}, - {file = "keyring-21.8.0.tar.gz", hash = "sha256:1746d3ac913d449a090caf11e9e4af00e26c3f7f7e81027872192b2398b98675"}, + {file = "keyring-22.0.1-py3-none-any.whl", hash = "sha256:9f44660a5d4931bdc14c08a1d01ef30b18a7a8147380710d8c9f9531e1f6c3c0"}, + {file = "keyring-22.0.1.tar.gz", hash = "sha256:9acb3e1452edbb7544822b12fd25459078769e560fa51f418b6d00afaa6178df"}, ] livereload = [ {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, From eca002ac290c9590e1f507088622663283f5f45a Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 30 Jan 2021 21:49:37 +0000 Subject: [PATCH 024/215] Update changelog [ci skip] --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3ba6eca..88b1286d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,15 @@ - Allow timestamps in command line for new entries with editor [\#1083](https://github.com/jrnl-org/jrnl/issues/1083) +**Fixed bugs:** + +- Make journal selection behavior more consistent when there's a colon with no date [\#1164](https://github.com/jrnl-org/jrnl/pull/1164) ([wren](https://github.com/wren)) + +**Packaging:** + +- Bump keyring from 21.8.0 to 22.0.1 [\#1168](https://github.com/jrnl-org/jrnl/pull/1168) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump pytest from 6.2.1 to 6.2.2 [\#1167](https://github.com/jrnl-org/jrnl/pull/1167) ([dependabot[bot]](https://github.com/apps/dependabot)) + ## [v2.7](https://pypi.org/project/jrnl/v2.7/) (2021-01-23) [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7-beta...v2.7) From 115f790210778d555d2e9950927398eada817ab8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Feb 2021 12:17:40 -0800 Subject: [PATCH 025/215] Bump pytz from 2020.5 to 2021.1 (#1174) Bumps [pytz](https://github.com/stub42/pytz) from 2020.5 to 2021.1. - [Release notes](https://github.com/stub42/pytz/releases) - [Commits](https://github.com/stub42/pytz/compare/release_2020.5...release_2021.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 50135423..276418d1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -457,7 +457,7 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2020.5" +version = "2021.1" description = "World timezone definitions, modern and historical" category = "main" optional = false @@ -768,20 +768,39 @@ markupsafe = [ {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"}, {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b"}, {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-win32.whl", hash = "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8"}, {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, ] mkdocs = [ @@ -843,8 +862,8 @@ python-dateutil = [ {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, ] pytz = [ - {file = "pytz-2020.5-py2.py3-none-any.whl", hash = "sha256:16962c5fb8db4a8f63a26646d8886e9d769b6c511543557bc84e9569fb9a9cb4"}, - {file = "pytz-2020.5.tar.gz", hash = "sha256:180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5"}, + {file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"}, + {file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"}, ] pywin32-ctypes = [ {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, From 3f3bdbeeda9acf4352b706b0bef5393a33721c02 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 6 Feb 2021 20:19:19 +0000 Subject: [PATCH 026/215] Update changelog [ci skip] --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88b1286d..4a199419 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,8 +12,13 @@ - Make journal selection behavior more consistent when there's a colon with no date [\#1164](https://github.com/jrnl-org/jrnl/pull/1164) ([wren](https://github.com/wren)) +**Documentation:** + +- Add the -a flag to documentation. [\#1119](https://github.com/jrnl-org/jrnl/issues/1119) + **Packaging:** +- Bump pytz from 2020.5 to 2021.1 [\#1174](https://github.com/jrnl-org/jrnl/pull/1174) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump keyring from 21.8.0 to 22.0.1 [\#1168](https://github.com/jrnl-org/jrnl/pull/1168) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump pytest from 6.2.1 to 6.2.2 [\#1167](https://github.com/jrnl-org/jrnl/pull/1167) ([dependabot[bot]](https://github.com/apps/dependabot)) From dc776b171acbdfba2dd554a0b2c163377a0a51c3 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 6 Feb 2021 14:10:21 -0800 Subject: [PATCH 027/215] Fix case on documentation tag in issue template --- .github/ISSUE_TEMPLATE/documentation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md index 24aacdd3..dc186ee9 100644 --- a/.github/ISSUE_TEMPLATE/documentation.md +++ b/.github/ISSUE_TEMPLATE/documentation.md @@ -2,7 +2,7 @@ name: Documentation Change about: Request or report any updates to our documentation (https://jrnl.sh) title: '' -labels: ":new:, Documentation" +labels: ":new:, documentation" assignees: '' --- From 2244672e33bea69dacc3a547671b96028c10f0d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 13 Feb 2021 11:13:24 -0800 Subject: [PATCH 028/215] Bump yq from 2.11.1 to 2.12.0 (#1186) Bumps [yq](https://github.com/kislyuk/yq) from 2.11.1 to 2.12.0. - [Release notes](https://github.com/kislyuk/yq/releases) - [Changelog](https://github.com/kislyuk/yq/blob/develop/Changes.rst) - [Commits](https://github.com/kislyuk/yq/compare/v2.11.1...v2.12.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 276418d1..c24c50bb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -587,7 +587,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "yq" -version = "2.11.1" +version = "2.12.0" description = "Command-line YAML/XML processor - jq wrapper for YAML/XML documents" category = "dev" optional = false @@ -596,6 +596,7 @@ python-versions = "*" [package.dependencies] argcomplete = ">=1.8.1" PyYAML = ">=3.11" +toml = ">=0.10.0" xmltodict = ">=0.11.0" [package.extras] @@ -683,6 +684,7 @@ cffi = [ {file = "cffi-1.14.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:840793c68105fe031f34d6a086eaea153a0cd5c491cde82a74b420edd0a2b909"}, {file = "cffi-1.14.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:b18e0a9ef57d2b41f5c68beefa32317d286c3d6ac0484efd10d6e07491bb95dd"}, {file = "cffi-1.14.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:045d792900a75e8b1e1b0ab6787dd733a8190ffcf80e8c8ceb2fb10a29ff238a"}, + {file = "cffi-1.14.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:7ef7d4ced6b325e92eb4d3502946c78c5367bc416398d387b39591532536734e"}, {file = "cffi-1.14.4-cp39-cp39-win32.whl", hash = "sha256:ba4e9e0ae13fc41c6b23299545e5ef73055213e466bd107953e4a013a5ddd7e3"}, {file = "cffi-1.14.4-cp39-cp39-win_amd64.whl", hash = "sha256:f032b34669220030f905152045dfa27741ce1a6db3324a5bc0b96b6c7420c87b"}, {file = "cffi-1.14.4.tar.gz", hash = "sha256:1a465cbe98a7fd391d47dce4b8f7e5b921e6cd805ef421d04f5f66ba8f06086c"}, @@ -1048,8 +1050,8 @@ xmltodict = [ {file = "xmltodict-0.12.0.tar.gz", hash = "sha256:50d8c638ed7ecb88d90561beedbf720c9b4e851a9fa6c47ebd64e99d166d8a21"}, ] yq = [ - {file = "yq-2.11.1-py2.py3-none-any.whl", hash = "sha256:c1e1d6abb6e80beacb9c40f9eb1105b6fc2a08d3dc908237f69f197e683cff1b"}, - {file = "yq-2.11.1.tar.gz", hash = "sha256:74f64e3784a34d8a18efd8addc83cf5ca3478a0a69517d70fd9158a3809f99e0"}, + {file = "yq-2.12.0-py2.py3-none-any.whl", hash = "sha256:1f124f48dee77ad5e0be8607777fed183e96c8d31fa577de14201c7a614e4819"}, + {file = "yq-2.12.0.tar.gz", hash = "sha256:1d2ad403504d306b5258b86c698f9856d7ad58b7bb17a2b875691a6a7b8c4c20"}, ] zipp = [ {file = "zipp-3.4.0-py3-none-any.whl", hash = "sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108"}, From 3df5c62b5e5d439c0c83b0f97a16f624def32da1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 13 Feb 2021 11:14:03 -0800 Subject: [PATCH 029/215] Bump cryptography from 3.3.1 to 3.4.4 (#1188) Bumps [cryptography](https://github.com/pyca/cryptography) from 3.3.1 to 3.4.4. - [Release notes](https://github.com/pyca/cryptography/releases) - [Changelog](https://github.com/pyca/cryptography/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/3.3.1...3.4.4) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index c24c50bb..d8dd2b4c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -129,22 +129,22 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "cryptography" -version = "3.3.1" +version = "3.4.4" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" +python-versions = ">=3.6" [package.dependencies] cffi = ">=1.12" -six = ">=1.4.1" [package.extras] docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] +sdist = ["setuptools-rust (>=0.11.4)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["pytest (>=3.6.0,!=3.9.0,!=3.9.1,!=3.9.2)", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] +test = ["pytest (>=6.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] [[package]] name = "future" @@ -698,20 +698,13 @@ colorama = [ {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] cryptography = [ - {file = "cryptography-3.3.1-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:c366df0401d1ec4e548bebe8f91d55ebcc0ec3137900d214dd7aac8427ef3030"}, - {file = "cryptography-3.3.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9f6b0492d111b43de5f70052e24c1f0951cb9e6022188ebcb1cc3a3d301469b0"}, - {file = "cryptography-3.3.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a69bd3c68b98298f490e84519b954335154917eaab52cf582fa2c5c7efc6e812"}, - {file = "cryptography-3.3.1-cp27-cp27m-win32.whl", hash = "sha256:84ef7a0c10c24a7773163f917f1cb6b4444597efd505a8aed0a22e8c4780f27e"}, - {file = "cryptography-3.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:594a1db4511bc4d960571536abe21b4e5c3003e8750ab8365fafce71c5d86901"}, - {file = "cryptography-3.3.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:0003a52a123602e1acee177dc90dd201f9bb1e73f24a070db7d36c588e8f5c7d"}, - {file = "cryptography-3.3.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:83d9d2dfec70364a74f4e7c70ad04d3ca2e6a08b703606993407bf46b97868c5"}, - {file = "cryptography-3.3.1-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:dc42f645f8f3a489c3dd416730a514e7a91a59510ddaadc09d04224c098d3302"}, - {file = "cryptography-3.3.1-cp36-abi3-manylinux1_x86_64.whl", hash = "sha256:788a3c9942df5e4371c199d10383f44a105d67d401fb4304178020142f020244"}, - {file = "cryptography-3.3.1-cp36-abi3-manylinux2010_x86_64.whl", hash = "sha256:69e836c9e5ff4373ce6d3ab311c1a2eed274793083858d3cd4c7d12ce20d5f9c"}, - {file = "cryptography-3.3.1-cp36-abi3-manylinux2014_aarch64.whl", hash = "sha256:9e21301f7a1e7c03dbea73e8602905a4ebba641547a462b26dd03451e5769e7c"}, - {file = "cryptography-3.3.1-cp36-abi3-win32.whl", hash = "sha256:b4890d5fb9b7a23e3bf8abf5a8a7da8e228f1e97dc96b30b95685df840b6914a"}, - {file = "cryptography-3.3.1-cp36-abi3-win_amd64.whl", hash = "sha256:0e85aaae861d0485eb5a79d33226dd6248d2a9f133b81532c8f5aae37de10ff7"}, - {file = "cryptography-3.3.1.tar.gz", hash = "sha256:7e177e4bea2de937a584b13645cab32f25e3d96fc0bc4a4cf99c27dc77682be6"}, + {file = "cryptography-3.4.4-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:287032b6a7d86abc98e8e977b20138c53fea40e5b24e29090d5a675a973dcd10"}, + {file = "cryptography-3.4.4-cp36-abi3-manylinux2010_x86_64.whl", hash = "sha256:7eed937ad9b53280a5f53570d3a7dc93cb4412b6a3d58d4c6bb78cc26319c729"}, + {file = "cryptography-3.4.4-cp36-abi3-manylinux2014_aarch64.whl", hash = "sha256:f21be9ec6b44c223b2024bbe59d394fadc7be320d18a8d595419afadb6cd5620"}, + {file = "cryptography-3.4.4-cp36-abi3-manylinux2014_x86_64.whl", hash = "sha256:dab437c2e84628703e3358f0f06555a6259bc5039209d51aa3b05af667ff4fd0"}, + {file = "cryptography-3.4.4-cp36-abi3-win32.whl", hash = "sha256:f6ea140d2736b7e1f0de4f988c43f76b0b3f3d365080e091715429ba218dce28"}, + {file = "cryptography-3.4.4-cp36-abi3-win_amd64.whl", hash = "sha256:288c65eea20bd89b11102c47b118bc1e0749386b0a0dfebba414076c5d4c8188"}, + {file = "cryptography-3.4.4.tar.gz", hash = "sha256:ee5e19f0856b6fbbdbab15c2787ca65d203801d2d65d0b8de6218f424206c848"}, ] future = [ {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"}, From 0d61e102c09409137e5c0058e3d40a916de9a46c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 13 Feb 2021 11:14:13 -0800 Subject: [PATCH 030/215] Bump asteval from 0.9.21 to 0.9.22 (#1189) Bumps [asteval](https://github.com/newville/asteval) from 0.9.21 to 0.9.22. - [Release notes](https://github.com/newville/asteval/releases) - [Commits](https://github.com/newville/asteval/compare/0.9.21...0.9.22) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/poetry.lock b/poetry.lock index d8dd2b4c..580b96f7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -33,7 +33,7 @@ test = ["coverage", "flake8", "pexpect", "wheel"] [[package]] name = "asteval" -version = "0.9.21" +version = "0.9.22" description = "Safe, minimalistic evaluator of python expression using ast module" category = "main" optional = false @@ -633,7 +633,7 @@ argcomplete = [ {file = "argcomplete-1.12.2.tar.gz", hash = "sha256:de0e1282330940d52ea92a80fea2e4b9e0da1932aaa570f84d268939d1897b04"}, ] asteval = [ - {file = "asteval-0.9.21.tar.gz", hash = "sha256:ee14ba2211cda1c76114e3e7b552cdd57e940309203d5f4106e6d6f2c2346a2e"}, + {file = "asteval-0.9.22.tar.gz", hash = "sha256:74a0939765fc6b1421e6672ccf74c52edc3c7af7d6a8298b057b0d50ac51aea8"}, ] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, From 76fd1324091624ed0af74848a534dd9a3034c385 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 13 Feb 2021 19:15:50 +0000 Subject: [PATCH 031/215] Update changelog [ci skip] --- CHANGELOG.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a199419..5ad7b677 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,12 +12,11 @@ - Make journal selection behavior more consistent when there's a colon with no date [\#1164](https://github.com/jrnl-org/jrnl/pull/1164) ([wren](https://github.com/wren)) -**Documentation:** - -- Add the -a flag to documentation. [\#1119](https://github.com/jrnl-org/jrnl/issues/1119) - **Packaging:** +- Bump asteval from 0.9.21 to 0.9.22 [\#1189](https://github.com/jrnl-org/jrnl/pull/1189) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump cryptography from 3.3.1 to 3.4.4 [\#1188](https://github.com/jrnl-org/jrnl/pull/1188) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump yq from 2.11.1 to 2.12.0 [\#1186](https://github.com/jrnl-org/jrnl/pull/1186) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump pytz from 2020.5 to 2021.1 [\#1174](https://github.com/jrnl-org/jrnl/pull/1174) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump keyring from 21.8.0 to 22.0.1 [\#1168](https://github.com/jrnl-org/jrnl/pull/1168) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump pytest from 6.2.1 to 6.2.2 [\#1167](https://github.com/jrnl-org/jrnl/pull/1167) ([dependabot[bot]](https://github.com/apps/dependabot)) From 487b0c44aef68fe0241af433f45acfb446600908 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 20 Feb 2021 11:30:33 -0800 Subject: [PATCH 032/215] Bump cryptography from 3.4.4 to 3.4.6 (#1195) Bumps [cryptography](https://github.com/pyca/cryptography) from 3.4.4 to 3.4.6. - [Release notes](https://github.com/pyca/cryptography/releases) - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/3.4.4...3.4.6) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/poetry.lock b/poetry.lock index 580b96f7..6418862f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -129,7 +129,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "cryptography" -version = "3.4.4" +version = "3.4.6" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false @@ -698,13 +698,13 @@ colorama = [ {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] cryptography = [ - {file = "cryptography-3.4.4-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:287032b6a7d86abc98e8e977b20138c53fea40e5b24e29090d5a675a973dcd10"}, - {file = "cryptography-3.4.4-cp36-abi3-manylinux2010_x86_64.whl", hash = "sha256:7eed937ad9b53280a5f53570d3a7dc93cb4412b6a3d58d4c6bb78cc26319c729"}, - {file = "cryptography-3.4.4-cp36-abi3-manylinux2014_aarch64.whl", hash = "sha256:f21be9ec6b44c223b2024bbe59d394fadc7be320d18a8d595419afadb6cd5620"}, - {file = "cryptography-3.4.4-cp36-abi3-manylinux2014_x86_64.whl", hash = "sha256:dab437c2e84628703e3358f0f06555a6259bc5039209d51aa3b05af667ff4fd0"}, - {file = "cryptography-3.4.4-cp36-abi3-win32.whl", hash = "sha256:f6ea140d2736b7e1f0de4f988c43f76b0b3f3d365080e091715429ba218dce28"}, - {file = "cryptography-3.4.4-cp36-abi3-win_amd64.whl", hash = "sha256:288c65eea20bd89b11102c47b118bc1e0749386b0a0dfebba414076c5d4c8188"}, - {file = "cryptography-3.4.4.tar.gz", hash = "sha256:ee5e19f0856b6fbbdbab15c2787ca65d203801d2d65d0b8de6218f424206c848"}, + {file = "cryptography-3.4.6-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:57ad77d32917bc55299b16d3b996ffa42a1c73c6cfa829b14043c561288d2799"}, + {file = "cryptography-3.4.6-cp36-abi3-manylinux2010_x86_64.whl", hash = "sha256:93cfe5b7ff006de13e1e89830810ecbd014791b042cbe5eec253be11ac2b28f3"}, + {file = "cryptography-3.4.6-cp36-abi3-manylinux2014_aarch64.whl", hash = "sha256:5ecf2bcb34d17415e89b546dbb44e73080f747e504273e4d4987630493cded1b"}, + {file = "cryptography-3.4.6-cp36-abi3-manylinux2014_x86_64.whl", hash = "sha256:fec7fb46b10da10d9e1d078d1ff8ed9e05ae14f431fdbd11145edd0550b9a964"}, + {file = "cryptography-3.4.6-cp36-abi3-win32.whl", hash = "sha256:df186fcbf86dc1ce56305becb8434e4b6b7504bc724b71ad7a3239e0c9d14ef2"}, + {file = "cryptography-3.4.6-cp36-abi3-win_amd64.whl", hash = "sha256:66b57a9ca4b3221d51b237094b0303843b914b7d5afd4349970bb26518e350b0"}, + {file = "cryptography-3.4.6.tar.gz", hash = "sha256:2d32223e5b0ee02943f32b19245b61a62db83a882f0e76cc564e1cec60d48f87"}, ] future = [ {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"}, From 0e90342b0284acc2dd2d65448ad663ba834647d7 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 20 Feb 2021 19:32:09 +0000 Subject: [PATCH 033/215] Update changelog [ci skip] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ad7b677..9eabe591 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ **Packaging:** +- Bump cryptography from 3.4.4 to 3.4.6 [\#1195](https://github.com/jrnl-org/jrnl/pull/1195) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump asteval from 0.9.21 to 0.9.22 [\#1189](https://github.com/jrnl-org/jrnl/pull/1189) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump cryptography from 3.3.1 to 3.4.4 [\#1188](https://github.com/jrnl-org/jrnl/pull/1188) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump yq from 2.11.1 to 2.12.0 [\#1186](https://github.com/jrnl-org/jrnl/pull/1186) ([dependabot[bot]](https://github.com/apps/dependabot)) From 021ec61a8119d69c35596863c7f9cdd6768b18a7 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 20 Feb 2021 19:50:52 +0000 Subject: [PATCH 034/215] Increment version to v2.7.1-beta --- jrnl/__version__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jrnl/__version__.py b/jrnl/__version__.py index 57da66a0..53f900b9 100644 --- a/jrnl/__version__.py +++ b/jrnl/__version__.py @@ -1 +1 @@ -__version__ = "v2.7" +__version__ = "v2.7.1-beta" diff --git a/pyproject.toml b/pyproject.toml index e47f27f7..6342f91a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "jrnl" -version = "v2.7" +version = "v2.7.1-beta" description = "Collect your thoughts and notes without leaving the command line." authors = [ "jrnl contributors ", From e6c0a16342a31bc2fca1e2e865646c27bd43d0b4 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 20 Feb 2021 19:52:38 +0000 Subject: [PATCH 035/215] Update changelog [ci skip] --- CHANGELOG.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9eabe591..057106ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,8 @@ # Changelog -## [Unreleased](https://github.com/jrnl-org/jrnl/) +## [v2.7.1-beta](https://pypi.org/project/jrnl/v2.7.1-beta/) (2021-02-20) -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7...HEAD) - -**Implemented enhancements:** - -- Allow timestamps in command line for new entries with editor [\#1083](https://github.com/jrnl-org/jrnl/issues/1083) +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7...v2.7.1-beta) **Fixed bugs:** From 67682e7e9347de7026d310f5f84a8586e83648d8 Mon Sep 17 00:00:00 2001 From: Suhas Date: Sat, 27 Feb 2021 13:53:21 -0500 Subject: [PATCH 036/215] Add per-journal config documentation (#1199) * update documentation with example config * make format * clarify meaning of config --- docs/advanced.md | 45 +++++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/docs/advanced.md b/docs/advanced.md index 51c4d1af..10da134b 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -1,5 +1,6 @@ + # Advanced Usage ## Configuration File @@ -19,29 +20,29 @@ and can be edited with a plain text editor. Backup your journal and config file before editing. Changes to the config file can have destructive effects on your journal! - - `journals` +- `journals` paths to your journal files - - `editor` +- `editor` if set, executes this command to launch an external editor for writing your entries, e.g. `vim`. Some editors require special options to work properly, see `FAQ ` for details. - - `encrypt` +- `encrypt` if `true`, encrypts your journal using AES. - - `tagsymbols` +- `tagsymbols` Symbols to be interpreted as tags. (See note below) - - `default_hour` and `default_minute` +- `default_hour` and `default_minute` if you supply a date, such as `last thursday`, but no specific time, the entry will be created at this time - - `timeformat` +- `timeformat` how to format the timestamps in your journal, see the [python docs](http://docs.python.org/library/time.html#time.strftime) for reference - - `highlight` +- `highlight` if `true`, tags will be highlighted in cyan. - - `linewrap` +- `linewrap` controls the width of the output. Set to `false` if you don't want to wrap long lines. - - `colors` +- `colors` dictionary that controls the colors used to display journal entries. It has four subkeys, which are: `body`, `date`, `tags`, and `title`. Current valid values are: `BLACK`, `RED`, `GREEN`, `YELLOW`, `BLUE`, `MAGENTA`, `CYAN`, `WHITE`, and `NONE`. `colorama.Fore` is used for colorization, and you can find the [docs here](https://github.com/tartley/colorama#colored-output). To disable colored output, set the value to `NONE`. If you set the value of any color subkey to an invalid color, no color will be used. - - `display_format` - specifies formatter to use, formatters available are: +- `display_format` + specifies formatter to use, formatters available are: `boxed`, `fancy`, `json`, `markdown`, `md`, `tags`, `text`, `txt`, `xml`, or `yaml`. !!! note @@ -99,11 +100,31 @@ food: ~/my_recipes.txt ``` Your `default` and your `food` journals won't be encrypted, however your -`work` journal will! You can override all options that are present at +`work` journal will! + +You can override all options that are present at the top level of `jrnl.yaml`, just make sure that at the very least you specify a `journal: ...` key that points to the journal file of that journal. +Consider the following example configuration + +```yaml +editor: vi -c startinsert +journals: + default: ~/journal.txt + work: + journal: ~/work.txt + encrypt: true + display_format: json + editor: code -rw + food: + display_format: markdown + journal: ~/recipes.txt +``` + +The `work` journal is encrypted, prints to `json` by default, and is edited using an existing window of VSCode. Similarly, the `food` journal prints to markdown by default, but uses all the other defaults. + !!! note Changing `encrypt` to a different value will not encrypt or decrypt your journal file, it merely says whether or not your journal From f7c78f63a093fa7fcfa8d357f46f8979ff036314 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 27 Feb 2021 18:55:07 +0000 Subject: [PATCH 037/215] Update changelog [ci skip] --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 057106ae..ec6c6f98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [Unreleased](https://github.com/jrnl-org/jrnl/) + +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7.1-beta...HEAD) + +**Documentation:** + +- Update documentation about journal-level config values [\#1196](https://github.com/jrnl-org/jrnl/issues/1196) +- update per-journal config documentation [\#1199](https://github.com/jrnl-org/jrnl/pull/1199) ([sriniv27](https://github.com/sriniv27)) + ## [v2.7.1-beta](https://pypi.org/project/jrnl/v2.7.1-beta/) (2021-02-20) [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7...v2.7.1-beta) From 2ac4bab4d5bbe4abc7cfd8ccff8c6609f2bde91b Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 27 Feb 2021 19:04:21 +0000 Subject: [PATCH 038/215] Increment version to v2.7.1 --- jrnl/__version__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jrnl/__version__.py b/jrnl/__version__.py index 53f900b9..36d130de 100644 --- a/jrnl/__version__.py +++ b/jrnl/__version__.py @@ -1 +1 @@ -__version__ = "v2.7.1-beta" +__version__ = "v2.7.1" diff --git a/pyproject.toml b/pyproject.toml index 6342f91a..e87de592 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "jrnl" -version = "v2.7.1-beta" +version = "v2.7.1" description = "Collect your thoughts and notes without leaving the command line." authors = [ "jrnl contributors ", From b99cebcee623a52dd1a5e7d66912deb747efff2b Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 27 Feb 2021 19:05:55 +0000 Subject: [PATCH 039/215] Update changelog [ci skip] --- CHANGELOG.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec6c6f98..f85eae2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,22 +1,18 @@ # Changelog -## [Unreleased](https://github.com/jrnl-org/jrnl/) +## [v2.7.1](https://pypi.org/project/jrnl/v2.7.1/) (2021-02-27) -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7.1-beta...HEAD) +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7.1-beta...v2.7.1) + +**Fixed bugs:** + +- Make journal selection behavior more consistent when there's a colon with no date [\#1164](https://github.com/jrnl-org/jrnl/pull/1164) ([wren](https://github.com/wren)) **Documentation:** - Update documentation about journal-level config values [\#1196](https://github.com/jrnl-org/jrnl/issues/1196) - update per-journal config documentation [\#1199](https://github.com/jrnl-org/jrnl/pull/1199) ([sriniv27](https://github.com/sriniv27)) -## [v2.7.1-beta](https://pypi.org/project/jrnl/v2.7.1-beta/) (2021-02-20) - -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7...v2.7.1-beta) - -**Fixed bugs:** - -- Make journal selection behavior more consistent when there's a colon with no date [\#1164](https://github.com/jrnl-org/jrnl/pull/1164) ([wren](https://github.com/wren)) - **Packaging:** - Bump cryptography from 3.4.4 to 3.4.6 [\#1195](https://github.com/jrnl-org/jrnl/pull/1195) ([dependabot[bot]](https://github.com/apps/dependabot)) From 4f79803885c955b1ce9cd908738085476d02b5e2 Mon Sep 17 00:00:00 2001 From: Suhas Date: Tue, 2 Mar 2021 21:47:57 -0500 Subject: [PATCH 040/215] Allow runtime configuration overrides from the commandline (#1169) Add --config-override feature * add test and argument handler for runtime override of configurations. * identify location to apply override in "main" * update gitignore * remove unneeded import * add jrnl interface test for overriden configurations * trivial whitespace change * implement runtime override * make format * refactor override unittest * clean up unused import * start writing integration test * add linewrap override scenario * implement editor override step * add dev dependencies on pytest -mock and -cov * make format * remove unused imports * make format * rename --override to --config-override * move override implementation into own module * begin TDD of dot notated overrides * rewrite behavior scenario * implement recursive config overrides * clean up unittests * iterate on behave step * make format * cleanup * move override behave tests out of core * refactor recursive code * make format * code cleanup * remove unused import * update test config * rewrite test for better mock call expect * make format * binary search misbehaving windows test * unittest multiple overrides * uncomment dot notation unittest * add multiple override scenario spec * make format * make format * update unittests for new syntax * update integ tests for new syntax * update gitignore * guard override application * deserialize function as return type * make format * organize deserialization unittests * better, more specific behave tests * test different editor launch commands * formatting * handle datatypes in deserialization and update helptext * stick to config convention in testbed * update tests ith better verifications * make format * space * review feedbac * make format * skip on win * update deps * update tests with better verifications make format space review feedbac * skip on win * update deps * refactor deserialization organize test_parse_args make format * skip on win * refactor deserialization organize test_parse_args make format * update tests ith better verifications * make format * space * make format * document apply_overrides * update gitignore * document config-override enhancement * Simplify config override syntax (#5) * update tests and expected behavior * clean up arg parsing tests * update deserialization * update deserialization * config argparse action * update override application logic * update tests; delete unused imports * override param must be list * update docstring * update test input to SUT * update remaining override unittests * make format * forgot to update CLI syntax * update documentation to sphinx style * variable renames * Lockfile merge (#7) * Add brew and gitter badges to README * Update changelog [ci skip] * Make journal selection behavior more consistent when there's a colon with no date (#1164) * Simplify config override syntax (#8) * update tests and expected behavior * clean up arg parsing tests * update deserialization * update deserialization * config argparse action * update override application logic * update tests; delete unused imports * override param must be list * update docstring * update test input to SUT * update remaining override unittests * make format * forgot to update CLI syntax * formatting * Update pyproject.toml * update lockfile to remove pytest-cov and pytest-mock deps * update docs * reuse existing mock; delete unneeded code * move overrides earlier in the execution use existing configs instead of custom make format clean up imports * update for passworded access context.parser -> parsed_args * test that no editor is launched * remove unnecessary mocks * rename variable for intent * reinstate getpass deletion * update gitignore * capture failure mode * remove unneeded imports * renamed variable * delete redundant step * comment on step * clean up step behavior description * [WIP] lock down journal access behavior * skip -> wip * correct command for overriding journal via dot keys * update wip test for updating a "temp" journal and then reading baack its entries * remove "mock" from poetry file * make CI happy * complex behavior sequence for default journal override * separate out smaller pieces of logic test that apply_overrides acts on base configuration and not the copy * defer modification of loaded configuration to update_config remove unused fixtures delete complicated UT since behavior is covered in overrides.feature integ test delete redundant UT * Update .gitignore * remove skip_win * forward override unpacking to yaml library * merge config override step with existing config_var step in core delete config_override step unify step description syntax * delete unused and redundant code * rebases are hard * remove wip tag from test * remove skipped tests for windows * Address code review yield -> return remove needless copy adjust spacing re-inline args return reset packaging info to e6c0a16342a31bc2fca1e2e865646c27bd43d0b4 revert package version for this PR * consolidate imports * Defer config_override unpacking to dict *after* base config is loaded store cli overrides without unpacking just yet move deserialize_config_args to config module delete custom Action class for config operations apply [k,v] -> {k, v} for each override update test data update import * rename deserialize_config_args to better express intent make format --- .gitignore | 7 +++ docs/advanced.md | 23 +++++++++ docs/recipes.md | 27 +++++++++++ features/overrides.feature | 98 ++++++++++++++++++++++++++++++++++++++ features/steps/core.py | 41 ++++++++++++++-- features/steps/override.py | 77 ++++++++++++++++++++++++++++++ jrnl/args.py | 23 +++++++++ jrnl/config.py | 26 ++++++++++ jrnl/jrnl.py | 7 +++ jrnl/override.py | 65 +++++++++++++++++++++++++ tests/test_override.py | 79 ++++++++++++++++++++++++++++++ tests/test_parse_args.py | 57 ++++++++++++++++++++++ 12 files changed, 526 insertions(+), 4 deletions(-) create mode 100644 features/overrides.feature create mode 100644 features/steps/override.py create mode 100644 jrnl/override.py create mode 100644 tests/test_override.py diff --git a/.gitignore b/.gitignore index afb0d874..374deb4b 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,10 @@ exp/ _extras/ *.sublime-* site/ + +.vscode/settings.json +coverage.xml +.vscode/launch.json +.coverage +.vscode/tasks.json +todo.txt diff --git a/docs/advanced.md b/docs/advanced.md index 10da134b..b1b7bef0 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -62,6 +62,29 @@ and can be edited with a plain text editor. Or use the built-in prompt or an external editor to compose your entries. +### Modifying Configurations from the Command line + +You can override a configuration field for the current instance of `jrnl` using `--config-override CONFIG_KEY CONFIG_VALUE` where `CONFIG_KEY` is a valid configuration field, specified in dot-notation and `CONFIG_VALUE` is the (valid) desired override value. + +You can specify multiple overrides as multiple calls to `--config-override`. +!!! note + These overrides allow you to modify ***any*** field of your jrnl configuration. We trust that you know what you are doing. + +#### Examples: + +``` sh +#Create an entry using the `stdin` prompt, for rapid logging +jrnl --config-override editor "" + +#Populate a project's log +jrnl --config-override journals.todo "$(git rev-parse --show-toplevel)/todo.txt" todo find my towel + +#Pass multiple overrides +jrnl --config-override display_format fancy --config-override linewrap 20 \ +--config-override colors.title green + +``` + ## Multiple journal files You can configure `jrnl`to use with multiple journals (eg. diff --git a/docs/recipes.md b/docs/recipes.md index 14e08e14..ef45666a 100644 --- a/docs/recipes.md +++ b/docs/recipes.md @@ -154,6 +154,33 @@ only field 1. jrnl -on "$(jrnl --short | shuf -n 1 | cut -d' ' -f1,2)" ``` + +### Launch a terminal for rapid logging +You can use this to launch a terminal that is the `jrnl` stdin prompt so you can start typing away immediately. + +```bash +jrnl now --config-override editor:"" +``` + +Bind this to a keyboard shortcut. + +Map `Super+Alt+J` to launch the terminal with jrnl prompt + +- **xbindkeys** +In your `.xbindkeysrc` + +```ini +Mod4+Mod1+j + alacritty -t floating-jrnl -e jrnl now --config-override editor:"", +``` + +- **I3 WM** Launch a floating terminal with the `jrnl` prompt + +```ini +bindsym Mod4+Mod1+j exec --no-startup-id alacritty -t floating-jrnl -e jrnl --config-override editor:"" +for_window[title="floating *"] floating enable +``` + ## External editors Configure your preferred external editor by updating the `editor` option diff --git a/features/overrides.feature b/features/overrides.feature new file mode 100644 index 00000000..e0cdd9f0 --- /dev/null +++ b/features/overrides.feature @@ -0,0 +1,98 @@ +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 + + 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 should have "highlight" set to "bool:false" + And no editor should 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 should have "colors.body" set to "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 should have "colors.body" set to "green" + And the config should have "editor" set to "nano" + + + Scenario Outline: Override configured 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 editor should have been called + Examples: Editor Commands + | editor | + | nano | + | vi -c startinsert | + | code -w | + + Scenario: Override default journal + Given we use the config "basic_dayone.yaml" + And we use the password "test" if prompted + When we run "jrnl --debug --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 --debug --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. + """ diff --git a/features/steps/core.py b/features/steps/core.py index abac4917..f471acfb 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -3,6 +3,7 @@ import ast from collections import defaultdict +from jrnl.args import parse_args import os from pathlib import Path import re @@ -13,8 +14,11 @@ from behave import given from behave import then from behave import when import keyring + import toml import yaml +from yaml.loader import FullLoader + import jrnl.time from jrnl import Journal @@ -23,6 +27,7 @@ from jrnl import plugins from jrnl.cli import cli from jrnl.config import load_config from jrnl.os_compat import split_args +from jrnl.override import apply_overrides, _recursively_apply try: import parsedatetime.parsedatetime_consts as pdt @@ -114,8 +119,15 @@ def read_value_from_string(string): return ast.literal_eval(string) # Takes strings like "bool:true" or "int:32" and coerces them into proper type - t, value = string.split(":") - value = {"bool": lambda v: v.lower() == "true", "int": int, "str": str}[t](value) + string_parts = string.split(":") + if len(string_parts) > 1: + type = string_parts[0] + value = string_parts[1:][0] # rest of the text + value = {"bool": lambda v: v.lower() == "true", "int": int, "str": str}[type]( + value + ) + else: + value = string_parts[0] return value @@ -315,6 +327,7 @@ def run_with_input(context, command, inputs=""): text = iter([inputs]) args = split_args(command)[1:] + context.args = args def _mock_editor(command): context.editor_command = command @@ -397,8 +410,13 @@ def run(context, command, text=""): if "cache_dir" in context and context.cache_dir is not None: cache_dir = os.path.join("features", "cache", context.cache_dir) command = command.format(cache_dir=cache_dir) + if "config_path" in context and context.config_path is not None: + with open(context.config_path, "r") as f: + cfg = yaml.load(f, Loader=FullLoader) + context.jrnl_config = cfg args = split_args(command) + context.args = args[1:] def _mock_editor(command): context.editor_command = command @@ -604,14 +622,29 @@ def journal_exists(context, journal_name="default"): @then('the config should have "{key}" set to "{value}"') @then('the config for journal "{journal}" should have "{key}" set to "{value}"') def config_var(context, key, value="", journal=None): + key_as_vec = key.split(".") + + if "args" in context: + parsed = parse_args(context.args) + overrides = parsed.config_override value = read_value_from_string(value or context.text or "") configuration = load_config(context.config_path) if journal: configuration = configuration["journals"][journal] - assert key in configuration - assert configuration[key] == value + if overrides: + with patch.object( + jrnl.override, "_recursively_apply", wraps=_recursively_apply + ) as spy_recurse: + configuration = apply_overrides(overrides, configuration) + runtime_cfg = spy_recurse.call_args_list[0][0][0] + else: + runtime_cfg = configuration + # extract the value of the desired key from the configuration after overrides have been applied + for k in key_as_vec: + runtime_cfg = runtime_cfg["%s" % k] + assert runtime_cfg == value @then('the config for journal "{journal}" should not have "{key}" set') diff --git a/features/steps/override.py b/features/steps/override.py new file mode 100644 index 00000000..ff1760ed --- /dev/null +++ b/features/steps/override.py @@ -0,0 +1,77 @@ +from jrnl.jrnl import run +from unittest import mock + +# from __future__ import with_statement +from jrnl.args import parse_args +from behave import then + +from features.steps.core import _mock_getpass, _mock_time_parse + + +@then("the editor {editor} should have been called") +@then("No editor should have been called") +def editor_override(context, editor=None): + def _mock_write_in_editor(config): + editor = config["editor"] + journal = "features/journals/journal.jrnl" + context.tmpfile = journal + print("%s has been launched" % editor) + return journal + + if "password" in context: + password = context.password + else: + password = "" + # fmt: off + # see: https://github.com/psf/black/issues/664 + with \ + mock.patch("jrnl.jrnl._write_in_editor", side_effect=_mock_write_in_editor(context.jrnl_config)) as mock_write_in_editor, \ + mock.patch("sys.stdin.isatty", return_value=True), \ + mock.patch('getpass.getpass',side_effect=_mock_getpass(password)), \ + mock.patch("jrnl.time.parse", side_effect = _mock_time_parse(context)), \ + mock.patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ + mock.patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ + : + try : + parsed_args = parse_args(context.args) + run(parsed_args) + context.exit_status = 0 + context.editor = mock_write_in_editor + expected_config = context.jrnl_config + expected_config['editor'] = '%s'%editor + expected_config['journal'] ='features/journals/journal.jrnl' + + if editor is not None: + assert mock_write_in_editor.call_count == 1 + assert mock_write_in_editor.call_args[0][0]['editor']==editor + else: + # Expect that editor is *never* called + mock_write_in_editor.assert_not_called() + except SystemExit as e: + context.exit_status = e.code + # fmt: on + + +@then("the stdin prompt should have been called") +def override_editor_to_use_stdin(context): + + try: + with mock.patch( + "sys.stdin.read", + return_value="Zwei peanuts walk into a bar und one of zem was a-salted", + ) as mock_stdin_read, mock.patch( + "jrnl.install.load_or_install_jrnl", return_value=context.jrnl_config + ), mock.patch( + "jrnl.Journal.open_journal", + spec=False, + return_value="features/journals/journal.jrnl", + ), mock.patch( + "getpass.getpass", side_effect=_mock_getpass("test") + ): + parsed_args = parse_args(context.args) + run(parsed_args) + context.exit_status = 0 + mock_stdin_read.assert_called_once() + + except SystemExit as e: + context.exit_status = e.code diff --git a/jrnl/args.py b/jrnl/args.py index f934ca16..c8bd7743 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -314,6 +314,29 @@ def parse_args(args=[]): help=argparse.SUPPRESS, ) + config_overrides = parser.add_argument_group( + "Config file override", + textwrap.dedent("Apply a one-off override of the config file option"), + ) + config_overrides.add_argument( + "--config-override", + dest="config_override", + action="append", + type=str, + nargs=2, + default=[], + metavar="CONFIG_KV_PAIR", + help=""" + Override configured key-value pair with CONFIG_KV_PAIR for this command invocation only. + + Examples: \n + \t - Use a different editor for this jrnl entry, call: \n + \t jrnl --config-override editor: "nano" \n + \t - Override color selections\n + \t jrnl --config-override colors.body blue --config-override colors.title green + """, + ) + # Handle '-123' as a shortcut for '-n 123' num = re.compile(r"^-(\d+)$") args = [num.sub(r"-n \1", arg) for arg in args] diff --git a/jrnl/config.py b/jrnl/config.py index a5a1d1cc..da2df2cc 100644 --- a/jrnl/config.py +++ b/jrnl/config.py @@ -19,6 +19,32 @@ XDG_RESOURCE = "jrnl" DEFAULT_JOURNAL_NAME = "journal.txt" DEFAULT_JOURNAL_KEY = "default" +YAML_SEPARATOR = ": " + + +def make_yaml_valid_dict(input: list) -> dict: + + """ + + Convert a two-element list of configuration key-value pair into a flat dict. + + The dict is created through the yaml loader, with the assumption that + "input[0]: input[1]" is valid yaml. + + :param input: list of configuration keys in dot-notation and their respective values. + :type input: list + :return: A single level dict of the configuration keys in dot-notation and their respective desired values + :rtype: dict + """ + + assert len(input) == 2 + + # yaml compatible strings are of the form Key:Value + yamlstr = YAML_SEPARATOR.join(input) + runtime_modifications = yaml.load(yamlstr, Loader=yaml.FullLoader) + + return runtime_modifications + def save_config(config): config["version"] = __version__ diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index 257358c4..383cceee 100644 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -16,6 +16,7 @@ from .editor import get_text_from_editor from .editor import get_text_from_stdin from .exception import UserAbort from . import time +from .override import apply_overrides def run(args): @@ -37,6 +38,12 @@ def run(args): try: config = install.load_or_install_jrnl() original_config = config.copy() + + # Apply config overrides + overrides = args.config_override + if overrides: + config = apply_overrides(overrides, config) + args = get_journal_name(args, config) config = scope_config(config, args.journal_name) except UserAbort as err: diff --git a/jrnl/override.py b/jrnl/override.py new file mode 100644 index 00000000..7fd718f0 --- /dev/null +++ b/jrnl/override.py @@ -0,0 +1,65 @@ +from .config import update_config, make_yaml_valid_dict + +# import logging +def apply_overrides(overrides: list, base_config: dict) -> dict: + """Unpack CLI provided overrides into the configuration tree. + + :param overrides: List of configuration key-value pairs collected from the CLI + :type overrides: list + :param base_config: Configuration Loaded from the saved YAML + :type base_config: dict + :return: Configuration to be used during runtime with the overrides applied + :rtype: dict + """ + cfg_with_overrides = base_config.copy() + for pairs in overrides: + + pairs = make_yaml_valid_dict(pairs) + key_as_dots, override_value = _get_key_and_value_from_pair(pairs) + keys = _convert_dots_to_list(key_as_dots) + cfg_with_overrides = _recursively_apply( + cfg_with_overrides, keys, override_value + ) + + update_config(base_config, cfg_with_overrides, None) + return base_config + + +def _get_key_and_value_from_pair(pairs): + key_as_dots, override_value = list(pairs.items())[0] + return key_as_dots, override_value + + +def _convert_dots_to_list(key_as_dots): + keys = key_as_dots.split(".") + keys = [k for k in keys if k != ""] # remove empty elements + return keys + + +def _recursively_apply(tree: dict, nodes: list, override_value) -> dict: + """Recurse through configuration and apply overrides at the leaf of the config tree + + Credit to iJames on SO: https://stackoverflow.com/a/47276490 for algorithm + + Args: + config (dict): Configuration to modify + nodes (list): Vector of override keys; the length of the vector indicates tree depth + override_value (str): Runtime override passed from the command-line + """ + key = nodes[0] + if len(nodes) == 1: + tree[key] = override_value + else: + next_key = nodes[1:] + next_node = _get_config_node(tree, key) + _recursively_apply(next_node, next_key, override_value) + + return tree + + +def _get_config_node(config: dict, key: str): + if key in config: + pass + else: + config[key] = None + return config[key] diff --git a/tests/test_override.py b/tests/test_override.py new file mode 100644 index 00000000..32ec0595 --- /dev/null +++ b/tests/test_override.py @@ -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 diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index 252638c9..4b140fc1 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -3,6 +3,7 @@ import shlex import pytest from jrnl.args import parse_args +from jrnl.config import make_yaml_valid_dict def cli_as_dict(str): @@ -35,6 +36,7 @@ def expected_args(**kwargs): "strict": False, "tags": False, "text": [], + "config_override": [], } return {**default_args, **kwargs} @@ -205,6 +207,31 @@ def test_version_alone(): 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", @@ -233,3 +260,33 @@ def test_and_ordering(cli): 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 From 1d222d67d51754a3a3ff78ceef7d304945b45b2d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Mar 2021 18:49:29 -0800 Subject: [PATCH 041/215] Bump asteval from 0.9.22 to 0.9.23 (#1209) Bumps [asteval](https://github.com/newville/asteval) from 0.9.22 to 0.9.23. - [Release notes](https://github.com/newville/asteval/releases) - [Commits](https://github.com/newville/asteval/compare/0.9.22...0.9.23) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/poetry.lock b/poetry.lock index 6418862f..860d37c1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -33,7 +33,7 @@ test = ["coverage", "flake8", "pexpect", "wheel"] [[package]] name = "asteval" -version = "0.9.22" +version = "0.9.23" description = "Safe, minimalistic evaluator of python expression using ast module" category = "main" optional = false @@ -633,7 +633,7 @@ argcomplete = [ {file = "argcomplete-1.12.2.tar.gz", hash = "sha256:de0e1282330940d52ea92a80fea2e4b9e0da1932aaa570f84d268939d1897b04"}, ] asteval = [ - {file = "asteval-0.9.22.tar.gz", hash = "sha256:74a0939765fc6b1421e6672ccf74c52edc3c7af7d6a8298b057b0d50ac51aea8"}, + {file = "asteval-0.9.23.tar.gz", hash = "sha256:f5096a924b1d2f147e70327245d95fc8f534dbe94277b6828ce2a8c049d3a438"}, ] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, @@ -699,11 +699,16 @@ colorama = [ ] cryptography = [ {file = "cryptography-3.4.6-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:57ad77d32917bc55299b16d3b996ffa42a1c73c6cfa829b14043c561288d2799"}, + {file = "cryptography-3.4.6-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:4169a27b818de4a1860720108b55a2801f32b6ae79e7f99c00d79f2a2822eeb7"}, {file = "cryptography-3.4.6-cp36-abi3-manylinux2010_x86_64.whl", hash = "sha256:93cfe5b7ff006de13e1e89830810ecbd014791b042cbe5eec253be11ac2b28f3"}, {file = "cryptography-3.4.6-cp36-abi3-manylinux2014_aarch64.whl", hash = "sha256:5ecf2bcb34d17415e89b546dbb44e73080f747e504273e4d4987630493cded1b"}, {file = "cryptography-3.4.6-cp36-abi3-manylinux2014_x86_64.whl", hash = "sha256:fec7fb46b10da10d9e1d078d1ff8ed9e05ae14f431fdbd11145edd0550b9a964"}, {file = "cryptography-3.4.6-cp36-abi3-win32.whl", hash = "sha256:df186fcbf86dc1ce56305becb8434e4b6b7504bc724b71ad7a3239e0c9d14ef2"}, {file = "cryptography-3.4.6-cp36-abi3-win_amd64.whl", hash = "sha256:66b57a9ca4b3221d51b237094b0303843b914b7d5afd4349970bb26518e350b0"}, + {file = "cryptography-3.4.6-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:066bc53f052dfeda2f2d7c195cf16fb3e5ff13e1b6b7415b468514b40b381a5b"}, + {file = "cryptography-3.4.6-pp36-pypy36_pp73-manylinux2014_x86_64.whl", hash = "sha256:600cf9bfe75e96d965509a4c0b2b183f74a4fa6f5331dcb40fb7b77b7c2484df"}, + {file = "cryptography-3.4.6-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:0923ba600d00718d63a3976f23cab19aef10c1765038945628cd9be047ad0336"}, + {file = "cryptography-3.4.6-pp37-pypy37_pp73-manylinux2014_x86_64.whl", hash = "sha256:9e98b452132963678e3ac6c73f7010fe53adf72209a32854d55690acac3f6724"}, {file = "cryptography-3.4.6.tar.gz", hash = "sha256:2d32223e5b0ee02943f32b19245b61a62db83a882f0e76cc564e1cec60d48f87"}, ] future = [ From 0560963c63208736cc64e95995bf761987c55b2b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Mar 2021 18:49:50 -0800 Subject: [PATCH 042/215] Bump keyring from 22.0.1 to 22.3.0 (#1210) Bumps [keyring](https://github.com/jaraco/keyring) from 22.0.1 to 22.3.0. - [Release notes](https://github.com/jaraco/keyring/releases) - [Changelog](https://github.com/jaraco/keyring/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/keyring/compare/v22.0.1...v22.3.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 860d37c1..4c558280 100644 --- a/poetry.lock +++ b/poetry.lock @@ -212,7 +212,7 @@ python-versions = ">=3.6" [[package]] name = "keyring" -version = "22.0.1" +version = "22.3.0" description = "Store and access your passwords safely." category = "main" optional = false @@ -226,7 +226,7 @@ SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "pytest-black (>=0.3.7)", "pytest-mypy"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "pytest-black (>=0.3.7)", "pytest-mypy"] [[package]] name = "livereload" @@ -735,8 +735,8 @@ joblib = [ {file = "joblib-0.17.0.tar.gz", hash = "sha256:9e284edd6be6b71883a63c9b7f124738a3c16195513ad940eae7e3438de885d5"}, ] keyring = [ - {file = "keyring-22.0.1-py3-none-any.whl", hash = "sha256:9f44660a5d4931bdc14c08a1d01ef30b18a7a8147380710d8c9f9531e1f6c3c0"}, - {file = "keyring-22.0.1.tar.gz", hash = "sha256:9acb3e1452edbb7544822b12fd25459078769e560fa51f418b6d00afaa6178df"}, + {file = "keyring-22.3.0-py3-none-any.whl", hash = "sha256:2bc8363ebdd63886126a012057a85c8cb6e143877afa02619ac7dbc9f38a207b"}, + {file = "keyring-22.3.0.tar.gz", hash = "sha256:16927a444b2c73f983520a48dec79ddab49fe76429ea05b8d528d778c8339522"}, ] livereload = [ {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, From 5a44385a542075269daf8a8bcdf06043bb992b63 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Wed, 3 Mar 2021 02:51:39 +0000 Subject: [PATCH 043/215] Update changelog [ci skip] --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f85eae2b..7a938b7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## [Unreleased](https://github.com/jrnl-org/jrnl/) + +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7.1...HEAD) + +**Implemented enhancements:** + +- Add `--config-override` feature [\#1169](https://github.com/jrnl-org/jrnl/pull/1169) ([sriniv27](https://github.com/sriniv27)) + +**Fixed bugs:** + +- bash: syntax error near unexpected token `newline' at input \>\_\> [\#1208](https://github.com/jrnl-org/jrnl/issues/1208) + +**Packaging:** + +- Bump keyring from 22.0.1 to 22.3.0 [\#1210](https://github.com/jrnl-org/jrnl/pull/1210) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump asteval from 0.9.22 to 0.9.23 [\#1209](https://github.com/jrnl-org/jrnl/pull/1209) ([dependabot[bot]](https://github.com/apps/dependabot)) + ## [v2.7.1](https://pypi.org/project/jrnl/v2.7.1/) (2021-02-27) [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7.1-beta...v2.7.1) From b9cf470871cbe691ce2bc2846a5d1bd7453bb93f Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 6 Mar 2021 07:18:35 -0800 Subject: [PATCH 044/215] Add pypi links for documentation, issue tracking, and funding (#1204) --- pyproject.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index e87de592..925a936c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,11 @@ classifiers = [ "Operating System :: OS Independent" ] +[tool.poetry.urls] +"Documentation" = "https://jrnl.sh" +"Issue Tracker" = "https://github.com/jrnl-org/jrnl/issues" +"Funding" = "https://opencollective.com/jrnl" + [tool.poetry.dependencies] python = ">=3.7.0, <3.10" From b9a6d029e21bb8f97fe7a720329f98ef323b16c8 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 6 Mar 2021 15:20:14 +0000 Subject: [PATCH 045/215] Update changelog [ci skip] --- CHANGELOG.md | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a938b7f..5d04559f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,22 +1,3 @@ -# Changelog - -## [Unreleased](https://github.com/jrnl-org/jrnl/) - -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7.1...HEAD) - -**Implemented enhancements:** - -- Add `--config-override` feature [\#1169](https://github.com/jrnl-org/jrnl/pull/1169) ([sriniv27](https://github.com/sriniv27)) - -**Fixed bugs:** - -- bash: syntax error near unexpected token `newline' at input \>\_\> [\#1208](https://github.com/jrnl-org/jrnl/issues/1208) - -**Packaging:** - -- Bump keyring from 22.0.1 to 22.3.0 [\#1210](https://github.com/jrnl-org/jrnl/pull/1210) ([dependabot[bot]](https://github.com/apps/dependabot)) -- Bump asteval from 0.9.22 to 0.9.23 [\#1209](https://github.com/jrnl-org/jrnl/pull/1209) ([dependabot[bot]](https://github.com/apps/dependabot)) - ## [v2.7.1](https://pypi.org/project/jrnl/v2.7.1/) (2021-02-27) [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7.1-beta...v2.7.1) @@ -616,6 +597,3 @@ ## v0.0 (2012-03-29) * __0.0.1__ Composing entries works. That's pretty much it. - - -\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* From a3f4f6b944984fae22d2eab8813caf5765095baf Mon Sep 17 00:00:00 2001 From: Suhas Date: Sat, 6 Mar 2021 13:47:03 -0500 Subject: [PATCH 046/215] Fix bug that prevented --format pretty and --format short from working (#1177) --- features/format.feature | 26 ++++++++++++++++++++++++++ features/steps/core.py | 6 ++++++ features/steps/export_steps.py | 2 +- jrnl/jrnl.py | 5 ++++- jrnl/plugins/__init__.py | 2 ++ tests/test_color.py | 17 +++++++++++++++++ tests/test_display.py | 23 +++++++++++++++++++++++ 7 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 tests/test_color.py create mode 100644 tests/test_display.py diff --git a/features/format.feature b/features/format.feature index 4981f685..7bdaac4d 100644 --- a/features/format.feature +++ b/features/format.feature @@ -1,5 +1,31 @@ Feature: Custom formats + Scenario Outline: Short printing via --format flag + Given We use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl --format short -3" + Then we should get no error + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario Outline: Pretty Printing aka the Default + Given We use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl --format pretty -3" + Then we should get no error + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + Scenario Outline: JSON format Given we use the config ".yaml" And we use the password "test" if prompted diff --git a/features/steps/core.py b/features/steps/core.py index f471acfb..ac5d8950 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -407,6 +407,12 @@ def all_input_was_used(context): def run(context, command, text=""): text = text or context.text or "" + if "config_path" in context and context.config_path is not None: + with open(context.config_path) as f: + context.jrnl_config = yaml.load(f, Loader=yaml.FullLoader) + else: + context.jrnl_config = None + if "cache_dir" in context and context.cache_dir is not None: cache_dir = os.path.join("features", "cache", context.cache_dir) command = command.format(cache_dir=cache_dir) diff --git a/features/steps/export_steps.py b/features/steps/export_steps.py index f885591c..3df86237 100644 --- a/features/steps/export_steps.py +++ b/features/steps/export_steps.py @@ -1,13 +1,13 @@ # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html + import json import os import shutil import random import string from xml.etree import ElementTree - from behave import given from behave import then diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index 383cceee..cf2b3bbb 100644 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -323,9 +323,12 @@ def _delete_search_results(journal, old_entries, **kwargs): def _display_search_results(args, journal, **kwargs): - if args.short: + if args.short or args.export == "short": print(journal.pprint(short=True)) + elif args.export == "pretty": + print(journal.pprint()) + elif args.tags: print(plugins.get_exporter("tags").export(journal)) diff --git a/jrnl/plugins/__init__.py b/jrnl/plugins/__init__.py index ad174f0b..3eb4d5a2 100644 --- a/jrnl/plugins/__init__.py +++ b/jrnl/plugins/__init__.py @@ -27,6 +27,8 @@ __exporters = [ __importers = [JRNLImporter] __exporter_types = {name: plugin for plugin in __exporters for name in plugin.names} +__exporter_types["pretty"] = None +__exporter_types["short"] = None __importer_types = {name: plugin for plugin in __importers for name in plugin.names} EXPORT_FORMATS = sorted(__exporter_types.keys()) diff --git a/tests/test_color.py b/tests/test_color.py new file mode 100644 index 00000000..14dc7938 --- /dev/null +++ b/tests/test_color.py @@ -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 diff --git a/tests/test_display.py b/tests/test_display.py new file mode 100644 index 00000000..72a9c451 --- /dev/null +++ b/tests/test_display.py @@ -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 From c3ddd7f2bfc20eadf8a3c08f40db65ff2e05ce1d Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 6 Mar 2021 18:48:31 +0000 Subject: [PATCH 047/215] Update changelog [ci skip] --- CHANGELOG.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d04559f..2e003e80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,26 @@ -## [v2.7.1](https://pypi.org/project/jrnl/v2.7.1/) (2021-02-27) +# Changelog + +## [Unreleased](https://github.com/jrnl-org/jrnl/) + +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7.1...HEAD) + +**Implemented enhancements:** + +- Add pypi project links [\#1197](https://github.com/jrnl-org/jrnl/issues/1197) +- Add `--config-override` feature [\#1169](https://github.com/jrnl-org/jrnl/pull/1169) ([sriniv27](https://github.com/sriniv27)) + +**Fixed bugs:** + +- bash: syntax error near unexpected token `newline' at input \>\_\> [\#1208](https://github.com/jrnl-org/jrnl/issues/1208) +- `jrnl --format short` returns an error [\#1173](https://github.com/jrnl-org/jrnl/issues/1173) +- `jrnl --format pretty` returns an error [\#1172](https://github.com/jrnl-org/jrnl/issues/1172) +- Fix bug that prevented --format pretty and --format short from working [\#1177](https://github.com/jrnl-org/jrnl/pull/1177) ([sriniv27](https://github.com/sriniv27)) + +**Packaging:** + +- Bump keyring from 22.0.1 to 22.3.0 [\#1210](https://github.com/jrnl-org/jrnl/pull/1210) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump asteval from 0.9.22 to 0.9.23 [\#1209](https://github.com/jrnl-org/jrnl/pull/1209) ([dependabot[bot]](https://github.com/apps/dependabot)) + [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7.1-beta...v2.7.1) @@ -597,3 +619,6 @@ ## v0.0 (2012-03-29) * __0.0.1__ Composing entries works. That's pretty much it. + + +\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* From 06e5b4baf61ab4bc2799608a0e419a53cd01e6ea Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 6 Mar 2021 13:47:11 -0800 Subject: [PATCH 048/215] Fix broken brew release process (#1211) * Add homebrew symlink for releases * Fix indentation problem * Fix bad env var name * Change filename to formula name * Fix formula name * Attempt tap instead of symlink * Fix formula repo referece * add tracer * Attempt working directory fix * Remove --unshallow * Use token for remote * Move set tap directory step * Remove tracer * Clean up spacing and wrap quotes to tap directory --- .github/workflows/release.yaml | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 3d57918a..7b4dfb18 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -116,7 +116,6 @@ jobs: HOMEBREW_NO_INSTALL_CLEANUP: 1 HOME_REPO: ${{ secrets.HOME_REPO }} steps: - - name: Get version run: | JRNL_VERSION="${{ github.event.inputs.version }}" @@ -153,23 +152,26 @@ jobs: } >> $GITHUB_ENV fi - - name: Checkout homebrew repo - uses: actions/checkout@v2 - with: - token: ${{ secrets.JRNL_BOT_TOKEN }} - repository: ${{ env.FORMULA_REPO }} + - name: Tap formula + run: | + brew tap ${FORMULA_REPO} + echo '::debug::Set tap directory' + echo "BREW_TAP_DIRECTORY='$(brew --repository)/Library/Taps/${FORMULA_REPO}'" >> $GITHUB_ENV - name: Config git user + working-directory: ${{ env.BREW_TAP_DIRECTORY }} run: | git config --global user.name "${{ secrets.JRNL_BOT_NAME }}" git config --global user.email "${{ secrets.JRNL_BOT_EMAIL }}" - name: Create branch + working-directory: ${{ env.BREW_TAP_DIRECTORY }} run: | BRANCH_NAME="jrnl-${JRNL_VERSION}--${RANDOM}" git remote rename origin upstream - git remote add origin "https://github.com/${BOT_REPO}.git" - git fetch --unshallow upstream + git remote add origin "https://${{ secrets.JRNL_BOT_NAME }}:${{ secrets.JRNL_BOT_TOKEN }}@github.com/${BOT_REPO}.git" + + git fetch upstream git fetch origin git checkout -b $BRANCH_NAME git push -u origin $BRANCH_NAME @@ -202,7 +204,7 @@ jobs: max_attempts: 6 retry_wait_seconds: 30 command: > - brew bump-formula-pr "Formula/${FORMULA_NAME}.rb" + brew bump-formula-pr "${FORMULA_NAME}" --url $(jq ".releases[\"${PYPI_VERSION}\"][1].url" -r api_response.json) --sha256 $(jq ".releases[\"${PYPI_VERSION}\"][1].digests.sha256" -r api_response.json) --version=$PYPI_VERSION @@ -213,6 +215,7 @@ jobs: --verbose - name: Update commit message + working-directory: ${{ env.BREW_TAP_DIRECTORY }} run: | git commit --amend \ -m "jrnl ${JRNL_VERSION}" \ @@ -220,11 +223,13 @@ jobs: -m '${{ secrets.RELEASE_COAUTHORS }}' - name: Push commit + working-directory: ${{ env.BREW_TAP_DIRECTORY }} run: | git show head git push - name: Open pull request + working-directory: ${{ env.BREW_TAP_DIRECTORY }} env: GH_TOKEN: ${{ secrets.JRNL_BOT_TOKEN }} run: > From 66395464132b3f034fc70c3074eb4bf188614dc8 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 6 Mar 2021 14:01:03 -0800 Subject: [PATCH 049/215] Remove global flag from git config --- .github/workflows/release.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 7b4dfb18..0c020811 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -161,8 +161,8 @@ jobs: - name: Config git user working-directory: ${{ env.BREW_TAP_DIRECTORY }} run: | - git config --global user.name "${{ secrets.JRNL_BOT_NAME }}" - git config --global user.email "${{ secrets.JRNL_BOT_EMAIL }}" + git config user.name "${{ secrets.JRNL_BOT_NAME }}" + git config user.email "${{ secrets.JRNL_BOT_EMAIL }}" - name: Create branch working-directory: ${{ env.BREW_TAP_DIRECTORY }} From df151d4dbce2369859a90097801dbd32e902b467 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 6 Mar 2021 14:05:48 -0800 Subject: [PATCH 050/215] Add --local flag in git config calls --- .github/workflows/release.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 0c020811..32912a9f 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -161,8 +161,8 @@ jobs: - name: Config git user working-directory: ${{ env.BREW_TAP_DIRECTORY }} run: | - git config user.name "${{ secrets.JRNL_BOT_NAME }}" - git config user.email "${{ secrets.JRNL_BOT_EMAIL }}" + git config --local user.name "${{ secrets.JRNL_BOT_NAME }}" + git config --local user.email "${{ secrets.JRNL_BOT_EMAIL }}" - name: Create branch working-directory: ${{ env.BREW_TAP_DIRECTORY }} From 1714d1eeef4ac3f366de619b5df95d7966d2839d Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 6 Mar 2021 22:18:39 +0000 Subject: [PATCH 051/215] Increment version to v2.7.2-beta --- jrnl/__version__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jrnl/__version__.py b/jrnl/__version__.py index 36d130de..3c06caa8 100644 --- a/jrnl/__version__.py +++ b/jrnl/__version__.py @@ -1 +1 @@ -__version__ = "v2.7.1" +__version__ = "v2.7.2-beta" diff --git a/pyproject.toml b/pyproject.toml index 925a936c..6950cd1f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "jrnl" -version = "v2.7.1" +version = "v2.7.2-beta" description = "Collect your thoughts and notes without leaving the command line." authors = [ "jrnl contributors ", From 98863bcc23703eaaed9df802f48d2767706f4ebb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 13 Mar 2021 11:09:59 -0800 Subject: [PATCH 052/215] Bump keyring from 22.3.0 to 23.0.0 (#1213) Bumps [keyring](https://github.com/jaraco/keyring) from 22.3.0 to 23.0.0. - [Release notes](https://github.com/jaraco/keyring/releases) - [Changelog](https://github.com/jaraco/keyring/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/keyring/compare/v22.3.0...v23.0.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4c558280..f92282e3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -156,18 +156,19 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "importlib-metadata" -version = "3.1.1" +version = "3.7.2" description = "Read metadata from Python packages" category = "main" optional = false python-versions = ">=3.6" [package.dependencies] +typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" @@ -212,14 +213,14 @@ python-versions = ">=3.6" [[package]] name = "keyring" -version = "22.3.0" +version = "23.0.0" description = "Store and access your passwords safely." category = "main" optional = false python-versions = ">=3.6" [package.dependencies] -importlib-metadata = {version = ">=1", markers = "python_version < \"3.8\""} +importlib-metadata = ">=3.6" jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""} pywin32-ctypes = {version = "<0.1.0 || >0.1.0,<0.1.1 || >0.1.1", markers = "sys_platform == \"win32\""} SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} @@ -562,7 +563,7 @@ python-versions = "*" name = "typing-extensions" version = "3.7.4.3" description = "Backported and Experimental Type Hints for Python 3.5+" -category = "dev" +category = "main" optional = false python-versions = "*" @@ -715,8 +716,8 @@ future = [ {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"}, ] importlib-metadata = [ - {file = "importlib_metadata-3.1.1-py3-none-any.whl", hash = "sha256:6112e21359ef8f344e7178aa5b72dc6e62b38b0d008e6d3cb212c5b84df72013"}, - {file = "importlib_metadata-3.1.1.tar.gz", hash = "sha256:b0c2d3b226157ae4517d9625decf63591461c66b3a808c2666d538946519d170"}, + {file = "importlib_metadata-3.7.2-py3-none-any.whl", hash = "sha256:407d13f55dc6f2a844e62325d18ad7019a436c4bfcaee34cda35f2be6e7c3e34"}, + {file = "importlib_metadata-3.7.2.tar.gz", hash = "sha256:18d5ff601069f98d5d605b6a4b50c18a34811d655c55548adc833e687289acde"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -735,8 +736,8 @@ joblib = [ {file = "joblib-0.17.0.tar.gz", hash = "sha256:9e284edd6be6b71883a63c9b7f124738a3c16195513ad940eae7e3438de885d5"}, ] keyring = [ - {file = "keyring-22.3.0-py3-none-any.whl", hash = "sha256:2bc8363ebdd63886126a012057a85c8cb6e143877afa02619ac7dbc9f38a207b"}, - {file = "keyring-22.3.0.tar.gz", hash = "sha256:16927a444b2c73f983520a48dec79ddab49fe76429ea05b8d528d778c8339522"}, + {file = "keyring-23.0.0-py3-none-any.whl", hash = "sha256:29f407fd5509c014a6086f17338c70215c8d1ab42d5d49e0254273bc0a64bbfc"}, + {file = "keyring-23.0.0.tar.gz", hash = "sha256:237ff44888ba9b3918a7dcb55c8f1db909c95b6f071bfb46c6918f33f453a68a"}, ] livereload = [ {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, From 1c66ac2da22665ee78e2acdba9970b1578254535 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 13 Mar 2021 19:29:14 +0000 Subject: [PATCH 053/215] Increment version to v2.8-beta --- jrnl/__version__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jrnl/__version__.py b/jrnl/__version__.py index 3c06caa8..790c604a 100644 --- a/jrnl/__version__.py +++ b/jrnl/__version__.py @@ -1 +1 @@ -__version__ = "v2.7.2-beta" +__version__ = "v2.8-beta" diff --git a/pyproject.toml b/pyproject.toml index 6950cd1f..32018559 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "jrnl" -version = "v2.7.2-beta" +version = "v2.8-beta" description = "Collect your thoughts and notes without leaving the command line." authors = [ "jrnl contributors ", From 7bacf4a5f0026d271e17b1558153bebfe9a40cde Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 13 Mar 2021 13:22:16 -0800 Subject: [PATCH 054/215] Changelog generator fixes There were several problems that this fixes: - shallow fetch broke merging to release branch - bad changelog was only outputting error msg (not exiting) - latest version being on first line deleted itself and broke the changelog updates This also has manual fixes to the changelog to bring it up to date. Co-authored-by: Micah Jerome Ellison --- .github/workflows/changelog.yaml | 9 +++++++++ CHANGELOG.md | 27 +++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/.github/workflows/changelog.yaml b/.github/workflows/changelog.yaml index dc52daed..c8d184ec 100644 --- a/.github/workflows/changelog.yaml +++ b/.github/workflows/changelog.yaml @@ -85,6 +85,13 @@ jobs: exit 1 fi + if [[ $tagline == 1 ]]; then + echo "::error::Something is wrong." + echo "::error::The latest release ${SINCE_TAG} is the first line in the changelog," + echo "::error::but the h1 '# Changelog' should always be the first line." + exit 1 + fi + sed -i "1,$(expr $tagline - 1)d" "$FILENAME" # delete generated line (or it will be added multiple times) sed -i '/This Changelog was automatically generated by/d' "$FILENAME" @@ -124,6 +131,7 @@ jobs: git diff if [[ $(grep -c '^# Changelog$' "$FILENAME") != 1 ]]; then echo '::error::Something is wrong with the changelog.' + exit 1 fi SOMETHING_CHANGED=false git diff --exit-code || SOMETHING_CHANGED=true @@ -142,6 +150,7 @@ jobs: - name: Merge to Release branch if: env.FULL_RELEASE == 'true' run: | + git fetch --unshallow origin git checkout release git merge --ff-only $BRANCH git push origin release diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e003e80..17059d78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,7 @@ # Changelog -## [Unreleased](https://github.com/jrnl-org/jrnl/) - -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7.1...HEAD) +## [v2.8-beta](https://pypi.org/project/jrnl/v2.8-beta/) (2021-03-13) +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7.2-beta...HEAD) **Implemented enhancements:** @@ -21,8 +20,28 @@ - Bump keyring from 22.0.1 to 22.3.0 [\#1210](https://github.com/jrnl-org/jrnl/pull/1210) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump asteval from 0.9.22 to 0.9.23 [\#1209](https://github.com/jrnl-org/jrnl/pull/1209) ([dependabot[bot]](https://github.com/apps/dependabot)) +## [v2.7.2-beta](https://pypi.org/project/jrnl/v2.7.2-beta/) (2021-03-06) +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7.1...v2.7.2-beta) -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7.1-beta...v2.7.1) +**Implemented enhancements:** + +- Add pypi project links [\#1197](https://github.com/jrnl-org/jrnl/issues/1197) +- Add `--config-override` feature [\#1169](https://github.com/jrnl-org/jrnl/pull/1169) ([sriniv27](https://github.com/sriniv27)) + +**Fixed bugs:** + +- bash: syntax error near unexpected token `newline' at input \>\_\> [\#1208](https://github.com/jrnl-org/jrnl/issues/1208) +- `jrnl --format short` returns an error [\#1173](https://github.com/jrnl-org/jrnl/issues/1173) +- `jrnl --format pretty` returns an error [\#1172](https://github.com/jrnl-org/jrnl/issues/1172) +- Fix bug that prevented --format pretty and --format short from working [\#1177](https://github.com/jrnl-org/jrnl/pull/1177) ([sriniv27](https://github.com/sriniv27)) + +**Packaging:** + +- Bump keyring from 22.0.1 to 22.3.0 [\#1210](https://github.com/jrnl-org/jrnl/pull/1210) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump asteval from 0.9.22 to 0.9.23 [\#1209](https://github.com/jrnl-org/jrnl/pull/1209) ([dependabot[bot]](https://github.com/apps/dependabot)) + +## [v2.7.1](https://pypi.org/project/jrnl/v2.7.1/) (2021-02-27) +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7...v2.7.1) **Fixed bugs:** From f849805a73b3828e5c13819e4ff7424ad231102b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 20 Mar 2021 10:55:59 -0700 Subject: [PATCH 055/215] Bump pyflakes from 2.2.0 to 2.3.0 (#1215) Bumps [pyflakes](https://github.com/PyCQA/pyflakes) from 2.2.0 to 2.3.0. - [Release notes](https://github.com/PyCQA/pyflakes/releases) - [Changelog](https://github.com/PyCQA/pyflakes/blob/master/NEWS.rst) - [Commits](https://github.com/PyCQA/pyflakes/compare/2.2.0...2.3.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index f92282e3..48e111ee 100644 --- a/poetry.lock +++ b/poetry.lock @@ -409,7 +409,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pyflakes" -version = "2.2.0" +version = "2.3.0" description = "passive checker of Python programs" category = "dev" optional = false @@ -847,8 +847,8 @@ pycparser = [ {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"}, ] pyflakes = [ - {file = "pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"}, - {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, + {file = "pyflakes-2.3.0-py2.py3-none-any.whl", hash = "sha256:910208209dcea632721cb58363d0f72913d9e8cf64dc6f8ae2e02a3609aba40d"}, + {file = "pyflakes-2.3.0.tar.gz", hash = "sha256:e59fd8e750e588358f1b8885e5a4751203a0516e0ee6d34811089ac294c8806f"}, ] pyparsing = [ {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, @@ -881,18 +881,26 @@ pyyaml = [ {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, From e116a95e34251e4b0963e7b9f6065d44c0de2f54 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 20 Mar 2021 13:08:59 -0700 Subject: [PATCH 056/215] Change PR steps for brew release The hub cli tool wasn't working anymore, so we took it out. Co-authored-by: Micah Jerome Ellison --- .github/workflows/release.yaml | 61 +++++++++++----------------------- 1 file changed, 20 insertions(+), 41 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 32912a9f..1631f901 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -127,7 +127,7 @@ jobs: echo "JRNL_VERSION=$JRNL_VERSION" >> $GITHUB_ENV echo "PYPI_VERSION=$PYPI_VERSION" >> $GITHUB_ENV - - name: Determine type of release + - name: Set env variables env: REPO_OWNER: ${{ github.repository_owner }} run: | @@ -158,24 +158,6 @@ jobs: echo '::debug::Set tap directory' echo "BREW_TAP_DIRECTORY='$(brew --repository)/Library/Taps/${FORMULA_REPO}'" >> $GITHUB_ENV - - name: Config git user - working-directory: ${{ env.BREW_TAP_DIRECTORY }} - run: | - git config --local user.name "${{ secrets.JRNL_BOT_NAME }}" - git config --local user.email "${{ secrets.JRNL_BOT_EMAIL }}" - - - name: Create branch - working-directory: ${{ env.BREW_TAP_DIRECTORY }} - run: | - BRANCH_NAME="jrnl-${JRNL_VERSION}--${RANDOM}" - git remote rename origin upstream - git remote add origin "https://${{ secrets.JRNL_BOT_NAME }}:${{ secrets.JRNL_BOT_TOKEN }}@github.com/${BOT_REPO}.git" - - git fetch upstream - git fetch origin - git checkout -b $BRANCH_NAME - git push -u origin $BRANCH_NAME - - name: Install dependencies run: brew install pipgrip @@ -210,29 +192,26 @@ jobs: --version=$PYPI_VERSION --no-audit --write - --commit --force - --verbose - - name: Update commit message - working-directory: ${{ env.BREW_TAP_DIRECTORY }} - run: | - git commit --amend \ - -m "jrnl ${JRNL_VERSION}" \ - -m "Update jrnl to ${JRNL_VERSION}" \ - -m '${{ secrets.RELEASE_COAUTHORS }}' + - name: Create Pull Request + uses: peter-evans/create-pull-request@v3 + with: + path: ${{ env.BREW_TAP_DIRECTORY }} + token: ${{ secrets.JRNL_BOT_TOKEN }} + push-to-fork: ${{ env.BOT_REPO }} - - name: Push commit - working-directory: ${{ env.BREW_TAP_DIRECTORY }} - run: | - git show head - git push + committer: ${{ secrets.JRNL_BOT_NAME }} <${{ secrets.JRNL_BOT_EMAIL }}> + author: ${{ secrets.JRNL_BOT_NAME }} <${{ secrets.JRNL_BOT_EMAIL }}> - - name: Open pull request - working-directory: ${{ env.BREW_TAP_DIRECTORY }} - env: - GH_TOKEN: ${{ secrets.JRNL_BOT_TOKEN }} - run: > - gh pr create - --title "jrnl ${JRNL_VERSION}" - --body 'Created with `brew bump-formula-pr`.' + title: jrnl ${{ env.JRNL_VERSION }} + body: Created with `brew bump-formula-pr` + + branch: jrnl-${{ env.JRNL_VERSION }}-- + branch-suffix: random + commit-message: | + jrnl ${{ env.JRNL_VERSION }} + + Update jrnl to ${{ env.JRNL_VERSION }} + + ${{ secrets.RELEASE_COAUTHORS }} From eb0c694cc83f52c208381f967447ec4700b9f366 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 20 Mar 2021 21:15:38 +0000 Subject: [PATCH 057/215] Update changelog [ci skip] --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17059d78..ca2f5a8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [Unreleased](https://github.com/jrnl-org/jrnl/) + +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8-beta...HEAD) + +**Implemented enhancements:** + +- Assigning a number to each entry when viewing [\#1218](https://github.com/jrnl-org/jrnl/issues/1218) + +**Packaging:** + +- Bump pyflakes from 2.2.0 to 2.3.0 [\#1215](https://github.com/jrnl-org/jrnl/pull/1215) ([dependabot[bot]](https://github.com/apps/dependabot)) + ## [v2.8-beta](https://pypi.org/project/jrnl/v2.8-beta/) (2021-03-13) [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7.2-beta...HEAD) From dc95b4c0988a6262a353d9dbbcc01685ce470f3c Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 27 Mar 2021 19:24:06 +0000 Subject: [PATCH 058/215] Increment version to v2.8 --- jrnl/__version__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jrnl/__version__.py b/jrnl/__version__.py index 790c604a..d01f99f3 100644 --- a/jrnl/__version__.py +++ b/jrnl/__version__.py @@ -1 +1 @@ -__version__ = "v2.8-beta" +__version__ = "v2.8" diff --git a/pyproject.toml b/pyproject.toml index 32018559..56773289 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "jrnl" -version = "v2.8-beta" +version = "v2.8" description = "Collect your thoughts and notes without leaving the command line." authors = [ "jrnl contributors ", From 50c053cf56027302062ceb1ad62cad86c8babc3e Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 27 Mar 2021 19:25:37 +0000 Subject: [PATCH 059/215] Update changelog [ci skip] --- CHANGELOG.md | 53 ++++++++++++---------------------------------------- 1 file changed, 12 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca2f5a8b..607f4e70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,54 +1,25 @@ # Changelog -## [Unreleased](https://github.com/jrnl-org/jrnl/) +## [v2.8](https://pypi.org/project/jrnl/v2.8/) (2021-03-27) -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8-beta...HEAD) +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8-beta...v2.8) **Implemented enhancements:** -- Assigning a number to each entry when viewing [\#1218](https://github.com/jrnl-org/jrnl/issues/1218) +- Add `--config-override` feature [\#1169](https://github.com/jrnl-org/jrnl/pull/1169) ([sriniv27](https://github.com/sriniv27)) + +**Fixed bugs:** + +- Fix bug that prevented --format pretty and --format short from working [\#1177](https://github.com/jrnl-org/jrnl/pull/1177) ([sriniv27](https://github.com/sriniv27)) + +**Build:** + +- Fix broken brew release process [\#1211](https://github.com/jrnl-org/jrnl/pull/1211) ([micahellison](https://github.com/micahellison)) **Packaging:** - Bump pyflakes from 2.2.0 to 2.3.0 [\#1215](https://github.com/jrnl-org/jrnl/pull/1215) ([dependabot[bot]](https://github.com/apps/dependabot)) - -## [v2.8-beta](https://pypi.org/project/jrnl/v2.8-beta/) (2021-03-13) -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7.2-beta...HEAD) - -**Implemented enhancements:** - -- Add pypi project links [\#1197](https://github.com/jrnl-org/jrnl/issues/1197) -- Add `--config-override` feature [\#1169](https://github.com/jrnl-org/jrnl/pull/1169) ([sriniv27](https://github.com/sriniv27)) - -**Fixed bugs:** - -- bash: syntax error near unexpected token `newline' at input \>\_\> [\#1208](https://github.com/jrnl-org/jrnl/issues/1208) -- `jrnl --format short` returns an error [\#1173](https://github.com/jrnl-org/jrnl/issues/1173) -- `jrnl --format pretty` returns an error [\#1172](https://github.com/jrnl-org/jrnl/issues/1172) -- Fix bug that prevented --format pretty and --format short from working [\#1177](https://github.com/jrnl-org/jrnl/pull/1177) ([sriniv27](https://github.com/sriniv27)) - -**Packaging:** - -- Bump keyring from 22.0.1 to 22.3.0 [\#1210](https://github.com/jrnl-org/jrnl/pull/1210) ([dependabot[bot]](https://github.com/apps/dependabot)) -- Bump asteval from 0.9.22 to 0.9.23 [\#1209](https://github.com/jrnl-org/jrnl/pull/1209) ([dependabot[bot]](https://github.com/apps/dependabot)) - -## [v2.7.2-beta](https://pypi.org/project/jrnl/v2.7.2-beta/) (2021-03-06) -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7.1...v2.7.2-beta) - -**Implemented enhancements:** - -- Add pypi project links [\#1197](https://github.com/jrnl-org/jrnl/issues/1197) -- Add `--config-override` feature [\#1169](https://github.com/jrnl-org/jrnl/pull/1169) ([sriniv27](https://github.com/sriniv27)) - -**Fixed bugs:** - -- bash: syntax error near unexpected token `newline' at input \>\_\> [\#1208](https://github.com/jrnl-org/jrnl/issues/1208) -- `jrnl --format short` returns an error [\#1173](https://github.com/jrnl-org/jrnl/issues/1173) -- `jrnl --format pretty` returns an error [\#1172](https://github.com/jrnl-org/jrnl/issues/1172) -- Fix bug that prevented --format pretty and --format short from working [\#1177](https://github.com/jrnl-org/jrnl/pull/1177) ([sriniv27](https://github.com/sriniv27)) - -**Packaging:** - +- Bump keyring from 22.3.0 to 23.0.0 [\#1213](https://github.com/jrnl-org/jrnl/pull/1213) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump keyring from 22.0.1 to 22.3.0 [\#1210](https://github.com/jrnl-org/jrnl/pull/1210) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump asteval from 0.9.22 to 0.9.23 [\#1209](https://github.com/jrnl-org/jrnl/pull/1209) ([dependabot[bot]](https://github.com/apps/dependabot)) From 09bcfa2242c4b667986bcf62906eae473884b342 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 27 Mar 2021 13:11:42 -0700 Subject: [PATCH 060/215] Update brew tap for release pipeline This was left out of a previous commit. Co-authored-by: Micah Jerome Ellison --- .github/workflows/release.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 1631f901..3e4987e9 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -156,8 +156,7 @@ jobs: run: | brew tap ${FORMULA_REPO} echo '::debug::Set tap directory' - echo "BREW_TAP_DIRECTORY='$(brew --repository)/Library/Taps/${FORMULA_REPO}'" >> $GITHUB_ENV - + echo "BREW_TAP_DIRECTORY=$(brew --repo ${FORMULA_REPO})" >> $GITHUB_ENV - name: Install dependencies run: brew install pipgrip From b357f935d4f8603ef35fe7361b45bd4691ad3c99 Mon Sep 17 00:00:00 2001 From: Mandar Vaze Date: Sun, 28 Mar 2021 01:51:44 +0530 Subject: [PATCH 061/215] Docs: Add emacs as external editor to recipes (#1220) Add emacs as external editor to recipes --- docs/recipes.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/recipes.md b/docs/recipes.md index ef45666a..1a1097d6 100644 --- a/docs/recipes.md +++ b/docs/recipes.md @@ -261,3 +261,14 @@ editor: "C:\\Program Files (x86)\\Notepad++\\notepad++.exe -multiInst -nosession The double backslashes are needed so jrnl can read the file path correctly. The `-multiInst -nosession` options will cause jrnl to open its own Notepad++ window. + + +### emacs + +To use `emacs` as your editor, edit the jrnl config file (`jrnl.yaml`) like this: + +```yaml +editor: emacsclient -a "" -c +``` + +When you're done editing the message, save and `C-x #` to close the buffer and stop the emacsclient process. From 6369026925df0927ff898845b0205f5452bcbe37 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 27 Mar 2021 13:23:05 -0700 Subject: [PATCH 062/215] Bump cryptography from 3.4.6 to 3.4.7 (#1223) Bumps [cryptography](https://github.com/pyca/cryptography) from 3.4.6 to 3.4.7. - [Release notes](https://github.com/pyca/cryptography/releases) - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/3.4.6...3.4.7) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/poetry.lock b/poetry.lock index 48e111ee..b003c4eb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -129,7 +129,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "cryptography" -version = "3.4.6" +version = "3.4.7" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false @@ -699,18 +699,18 @@ colorama = [ {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] cryptography = [ - {file = "cryptography-3.4.6-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:57ad77d32917bc55299b16d3b996ffa42a1c73c6cfa829b14043c561288d2799"}, - {file = "cryptography-3.4.6-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:4169a27b818de4a1860720108b55a2801f32b6ae79e7f99c00d79f2a2822eeb7"}, - {file = "cryptography-3.4.6-cp36-abi3-manylinux2010_x86_64.whl", hash = "sha256:93cfe5b7ff006de13e1e89830810ecbd014791b042cbe5eec253be11ac2b28f3"}, - {file = "cryptography-3.4.6-cp36-abi3-manylinux2014_aarch64.whl", hash = "sha256:5ecf2bcb34d17415e89b546dbb44e73080f747e504273e4d4987630493cded1b"}, - {file = "cryptography-3.4.6-cp36-abi3-manylinux2014_x86_64.whl", hash = "sha256:fec7fb46b10da10d9e1d078d1ff8ed9e05ae14f431fdbd11145edd0550b9a964"}, - {file = "cryptography-3.4.6-cp36-abi3-win32.whl", hash = "sha256:df186fcbf86dc1ce56305becb8434e4b6b7504bc724b71ad7a3239e0c9d14ef2"}, - {file = "cryptography-3.4.6-cp36-abi3-win_amd64.whl", hash = "sha256:66b57a9ca4b3221d51b237094b0303843b914b7d5afd4349970bb26518e350b0"}, - {file = "cryptography-3.4.6-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:066bc53f052dfeda2f2d7c195cf16fb3e5ff13e1b6b7415b468514b40b381a5b"}, - {file = "cryptography-3.4.6-pp36-pypy36_pp73-manylinux2014_x86_64.whl", hash = "sha256:600cf9bfe75e96d965509a4c0b2b183f74a4fa6f5331dcb40fb7b77b7c2484df"}, - {file = "cryptography-3.4.6-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:0923ba600d00718d63a3976f23cab19aef10c1765038945628cd9be047ad0336"}, - {file = "cryptography-3.4.6-pp37-pypy37_pp73-manylinux2014_x86_64.whl", hash = "sha256:9e98b452132963678e3ac6c73f7010fe53adf72209a32854d55690acac3f6724"}, - {file = "cryptography-3.4.6.tar.gz", hash = "sha256:2d32223e5b0ee02943f32b19245b61a62db83a882f0e76cc564e1cec60d48f87"}, + {file = "cryptography-3.4.7-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:3d8427734c781ea5f1b41d6589c293089704d4759e34597dce91014ac125aad1"}, + {file = "cryptography-3.4.7-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:8e56e16617872b0957d1c9742a3f94b43533447fd78321514abbe7db216aa250"}, + {file = "cryptography-3.4.7-cp36-abi3-manylinux2010_x86_64.whl", hash = "sha256:37340614f8a5d2fb9aeea67fd159bfe4f5f4ed535b1090ce8ec428b2f15a11f2"}, + {file = "cryptography-3.4.7-cp36-abi3-manylinux2014_aarch64.whl", hash = "sha256:240f5c21aef0b73f40bb9f78d2caff73186700bf1bc6b94285699aff98cc16c6"}, + {file = "cryptography-3.4.7-cp36-abi3-manylinux2014_x86_64.whl", hash = "sha256:1e056c28420c072c5e3cb36e2b23ee55e260cb04eee08f702e0edfec3fb51959"}, + {file = "cryptography-3.4.7-cp36-abi3-win32.whl", hash = "sha256:0f1212a66329c80d68aeeb39b8a16d54ef57071bf22ff4e521657b27372e327d"}, + {file = "cryptography-3.4.7-cp36-abi3-win_amd64.whl", hash = "sha256:de4e5f7f68220d92b7637fc99847475b59154b7a1b3868fb7385337af54ac9ca"}, + {file = "cryptography-3.4.7-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:26965837447f9c82f1855e0bc8bc4fb910240b6e0d16a664bb722df3b5b06873"}, + {file = "cryptography-3.4.7-pp36-pypy36_pp73-manylinux2014_x86_64.whl", hash = "sha256:eb8cc2afe8b05acbd84a43905832ec78e7b3873fb124ca190f574dca7389a87d"}, + {file = "cryptography-3.4.7-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:7ec5d3b029f5fa2b179325908b9cd93db28ab7b85bb6c1db56b10e0b54235177"}, + {file = "cryptography-3.4.7-pp37-pypy37_pp73-manylinux2014_x86_64.whl", hash = "sha256:ee77aa129f481be46f8d92a1a7db57269a2f23052d5f2433b4621bb457081cc9"}, + {file = "cryptography-3.4.7.tar.gz", hash = "sha256:3d10de8116d25649631977cb37da6cbdd2d6fa0e0281d014a5b7d337255ca713"}, ] future = [ {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"}, From e76762dd4dfd94bf68050dc27f44f8b13f927a53 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 27 Mar 2021 20:24:44 +0000 Subject: [PATCH 063/215] Update changelog [ci skip] --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 607f4e70..a8d4cb8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [Unreleased](https://github.com/jrnl-org/jrnl/) + +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8...HEAD) + +**Documentation:** + +- Docs: Add emacs as external editor to recipes [\#1220](https://github.com/jrnl-org/jrnl/pull/1220) ([mandarvaze](https://github.com/mandarvaze)) + +**Packaging:** + +- Bump cryptography from 3.4.6 to 3.4.7 [\#1223](https://github.com/jrnl-org/jrnl/pull/1223) ([dependabot[bot]](https://github.com/apps/dependabot)) + ## [v2.8](https://pypi.org/project/jrnl/v2.8/) (2021-03-27) [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8-beta...v2.8) From 1e7d682df5da4a99a25da4f0327a0219e6af0fd8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 27 Mar 2021 13:40:49 -0700 Subject: [PATCH 064/215] Bump pyflakes from 2.3.0 to 2.3.1 (#1221) Bumps [pyflakes](https://github.com/PyCQA/pyflakes) from 2.3.0 to 2.3.1. - [Release notes](https://github.com/PyCQA/pyflakes/releases) - [Changelog](https://github.com/PyCQA/pyflakes/blob/master/NEWS.rst) - [Commits](https://github.com/PyCQA/pyflakes/compare/2.3.0...2.3.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index b003c4eb..d179968a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -409,7 +409,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pyflakes" -version = "2.3.0" +version = "2.3.1" description = "passive checker of Python programs" category = "dev" optional = false @@ -847,8 +847,8 @@ pycparser = [ {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"}, ] pyflakes = [ - {file = "pyflakes-2.3.0-py2.py3-none-any.whl", hash = "sha256:910208209dcea632721cb58363d0f72913d9e8cf64dc6f8ae2e02a3609aba40d"}, - {file = "pyflakes-2.3.0.tar.gz", hash = "sha256:e59fd8e750e588358f1b8885e5a4751203a0516e0ee6d34811089ac294c8806f"}, + {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, + {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, ] pyparsing = [ {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, From 002a39db2a798ec43e471c871c6af7e7b8081080 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 27 Mar 2021 13:41:11 -0700 Subject: [PATCH 065/215] Bump keyring from 23.0.0 to 23.0.1 (#1222) Bumps [keyring](https://github.com/jaraco/keyring) from 23.0.0 to 23.0.1. - [Release notes](https://github.com/jaraco/keyring/releases) - [Changelog](https://github.com/jaraco/keyring/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/keyring/compare/v23.0.0...v23.0.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index d179968a..a851f03e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -213,7 +213,7 @@ python-versions = ">=3.6" [[package]] name = "keyring" -version = "23.0.0" +version = "23.0.1" description = "Store and access your passwords safely." category = "main" optional = false @@ -227,7 +227,7 @@ SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "pytest-black (>=0.3.7)", "pytest-mypy"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-black (>=0.3.7)", "pytest-mypy"] [[package]] name = "livereload" @@ -736,8 +736,8 @@ joblib = [ {file = "joblib-0.17.0.tar.gz", hash = "sha256:9e284edd6be6b71883a63c9b7f124738a3c16195513ad940eae7e3438de885d5"}, ] keyring = [ - {file = "keyring-23.0.0-py3-none-any.whl", hash = "sha256:29f407fd5509c014a6086f17338c70215c8d1ab42d5d49e0254273bc0a64bbfc"}, - {file = "keyring-23.0.0.tar.gz", hash = "sha256:237ff44888ba9b3918a7dcb55c8f1db909c95b6f071bfb46c6918f33f453a68a"}, + {file = "keyring-23.0.1-py3-none-any.whl", hash = "sha256:8f607d7d1cc502c43a932a275a56fe47db50271904513a379d39df1af277ac48"}, + {file = "keyring-23.0.1.tar.gz", hash = "sha256:045703609dd3fccfcdb27da201684278823b72af515aedec1a8515719a038cb8"}, ] livereload = [ {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, From eebadd188aa4a1c37057dd2a281a9aee53dbd065 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 27 Mar 2021 20:42:44 +0000 Subject: [PATCH 066/215] Update changelog [ci skip] --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8d4cb8b..e35227ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ **Packaging:** - Bump cryptography from 3.4.6 to 3.4.7 [\#1223](https://github.com/jrnl-org/jrnl/pull/1223) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump keyring from 23.0.0 to 23.0.1 [\#1222](https://github.com/jrnl-org/jrnl/pull/1222) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump pyflakes from 2.3.0 to 2.3.1 [\#1221](https://github.com/jrnl-org/jrnl/pull/1221) ([dependabot[bot]](https://github.com/apps/dependabot)) ## [v2.8](https://pypi.org/project/jrnl/v2.8/) (2021-03-27) From 202859cea1f4a7f263fd2299848541312f198da3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 10 Apr 2021 11:50:37 -0700 Subject: [PATCH 067/215] Bump pytest from 6.2.2 to 6.2.3 (#1228) Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.2.2 to 6.2.3. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/6.2.2...6.2.3) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index a851f03e..58769e8c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -425,7 +425,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "pytest" -version = "6.2.2" +version = "6.2.3" description = "pytest: simple powerful testing with Python" category = "dev" optional = false @@ -855,8 +855,8 @@ pyparsing = [ {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pytest = [ - {file = "pytest-6.2.2-py3-none-any.whl", hash = "sha256:b574b57423e818210672e07ca1fa90aaf194a4f63f3ab909a2c67ebb22913839"}, - {file = "pytest-6.2.2.tar.gz", hash = "sha256:9d1edf9e7d0b84d72ea3dbcdfd22b35fb543a5e8f2a60092dd578936bf63d7f9"}, + {file = "pytest-6.2.3-py3-none-any.whl", hash = "sha256:6ad9c7bdf517a808242b998ac20063c41532a570d088d77eec1ee12b0b5574bc"}, + {file = "pytest-6.2.3.tar.gz", hash = "sha256:671238a46e4df0f3498d1c3270e5deb9b32d25134c99b7d75370a68cfbe9b634"}, ] python-dateutil = [ {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, From 1f19bd9f1e505540e5e0acd1808a7aef0cfac775 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 10 Apr 2021 18:52:04 +0000 Subject: [PATCH 068/215] Update changelog [ci skip] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e35227ad..408f9b4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ **Packaging:** +- Bump pytest from 6.2.2 to 6.2.3 [\#1228](https://github.com/jrnl-org/jrnl/pull/1228) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump cryptography from 3.4.6 to 3.4.7 [\#1223](https://github.com/jrnl-org/jrnl/pull/1223) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump keyring from 23.0.0 to 23.0.1 [\#1222](https://github.com/jrnl-org/jrnl/pull/1222) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump pyflakes from 2.3.0 to 2.3.1 [\#1221](https://github.com/jrnl-org/jrnl/pull/1221) ([dependabot[bot]](https://github.com/apps/dependabot)) From dd74b14d76de6c29f1ea37ad239aa3092b7e4d6b Mon Sep 17 00:00:00 2001 From: Suhas Date: Sat, 10 Apr 2021 19:49:56 -0400 Subject: [PATCH 069/215] More graceful handling of low linewrap values (#1219) * behavior outline * enforce positive initial linewrap Check column widths update gitignore throw error when linewrap too small simply check for large enough linewrap value * delete unused error message * PR feedback make exception more informative update check_linewrap signature in src and test make check_linewrap a free function * delete unused function * delete else..pass block * newline for make format --- features/format.feature | 16 ++++++++++++++++ features/steps/export_steps.py | 8 ++++++++ jrnl/exception.py | 10 +++++++++- jrnl/plugins/fancy_exporter.py | 19 ++++++++++++++++++- tests/test_export.py | 28 ++++++++++++++++++++++++++++ 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 tests/test_export.py diff --git a/features/format.feature b/features/format.feature index 7bdaac4d..f935e8c8 100644 --- a/features/format.feature +++ b/features/format.feature @@ -323,6 +323,22 @@ Feature: Custom formats | basic_folder | | basic_dayone | + + + Scenario Outline: Export fancy with small linewrap + Given we use the config ".yaml" + 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 | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + @todo Scenario Outline: Exporting fancy # Needs better emoji support diff --git a/features/steps/export_steps.py b/features/steps/export_steps.py index 3df86237..8141dc36 100644 --- a/features/steps/export_steps.py +++ b/features/steps/export_steps.py @@ -12,6 +12,14 @@ from behave import given from behave import then +@then("the output should be {width:d} columns wide") +def check_output_width(context, width): + out = context.stdout_capture.getvalue() + out_lines = out.splitlines() + for line in out_lines: + assert len(line) <= width + + @then("the output should be parsable as json") def check_output_json(context): out = context.stdout_capture.getvalue() diff --git a/jrnl/exception.py b/jrnl/exception.py index 82a562a0..ac7cd0b2 100644 --- a/jrnl/exception.py +++ b/jrnl/exception.py @@ -30,7 +30,15 @@ class JrnlError(Exception): Removing this file will allow jrnl to save its configuration. """ - ) + ), + "LineWrapTooSmallForDateFormat": textwrap.dedent( + """ + The provided linewrap value of {config_linewrap} is too small by {columns} columns + to display the timestamps in the configured time format for journal {journal}. + + You can avoid this error by specifying a linewrap value that is larger by at least {columns} in the configuration file or by using --config-override at the command line + """ + ), } return error_messages[self.error_type].format(**kwargs) diff --git a/jrnl/plugins/fancy_exporter.py b/jrnl/plugins/fancy_exporter.py index 74cc6958..15efc19b 100644 --- a/jrnl/plugins/fancy_exporter.py +++ b/jrnl/plugins/fancy_exporter.py @@ -3,6 +3,7 @@ # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html +from jrnl.exception import JrnlError from textwrap import TextWrapper from .text_exporter import TextExporter @@ -14,12 +15,14 @@ class FancyExporter(TextExporter): names = ["fancy", "boxed"] extension = "txt" + # Top border of the card border_a = "┎" border_b = "─" border_c = "╮" border_d = "╘" border_e = "═" border_f = "╕" + border_g = "┃" border_h = "│" border_i = "┠" @@ -33,16 +36,19 @@ class FancyExporter(TextExporter): """Returns a fancy unicode representation of a single entry.""" date_str = entry.date.strftime(entry.journal.config["timeformat"]) linewrap = entry.journal.config["linewrap"] or 78 - initial_linewrap = linewrap - len(date_str) - 2 + initial_linewrap = max((1, linewrap - len(date_str) - 2)) body_linewrap = linewrap - 2 card = [ cls.border_a + cls.border_b * (initial_linewrap) + cls.border_c + date_str ] + check_provided_linewrap_viability(linewrap, card, entry.journal) + w = TextWrapper( width=initial_linewrap, initial_indent=cls.border_g + " ", subsequent_indent=cls.border_g + " ", ) + title_lines = w.wrap(entry.title) card.append( title_lines[0].ljust(initial_linewrap + 1) @@ -74,3 +80,14 @@ class FancyExporter(TextExporter): def export_journal(cls, journal): """Returns a unicode representation of an entire journal.""" return "\n".join(cls.export_entry(entry) for entry in journal) + + +def check_provided_linewrap_viability(linewrap, card, journal): + if len(card[0]) > linewrap: + width_violation = len(card[0]) - linewrap + raise JrnlError( + "LineWrapTooSmallForDateFormat", + config_linewrap=linewrap, + columns=width_violation, + journal=journal, + ) diff --git a/tests/test_export.py b/tests/test_export.py new file mode 100644 index 00000000..0f494f79 --- /dev/null +++ b/tests/test_export.py @@ -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" From 192c05ce0d63c4e69e727a52e96e97c631f1b75b Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 10 Apr 2021 23:51:26 +0000 Subject: [PATCH 070/215] Update changelog [ci skip] --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 408f9b4f..8765f5a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8...HEAD) +**Fixed bugs:** + +- Fancy format crashes on low linewrap values [\#1201](https://github.com/jrnl-org/jrnl/issues/1201) +- More graceful handling of low linewrap values [\#1219](https://github.com/jrnl-org/jrnl/pull/1219) ([sriniv27](https://github.com/sriniv27)) + **Documentation:** - Docs: Add emacs as external editor to recipes [\#1220](https://github.com/jrnl-org/jrnl/pull/1220) ([mandarvaze](https://github.com/mandarvaze)) From 4c5d59a5bc09becd5ed81f3f940eec75cd4d3571 Mon Sep 17 00:00:00 2001 From: Manuel Ebert Date: Thu, 15 Apr 2021 00:47:10 -0500 Subject: [PATCH 071/215] Update index.html (#1229) --- docs_theme/index.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs_theme/index.html b/docs_theme/index.html index 491da4c7..b21493d2 100755 --- a/docs_theme/index.html +++ b/docs_theme/index.html @@ -7,18 +7,18 @@ jrnl - The Command Line Journal - + - + - + - + @@ -35,8 +35,8 @@ "name": "jrnl", "description": "Collect your thoughts and notes without leaving the command line.", "operatingSystem": ["macOS", "Windows", "Linux"], - "thumbnailUrl": "https://jrnl.sh/img/banner_og.png", - "installUrl": "https://jrnl.sh/installation", + "thumbnailUrl": "https://jrnl.sh/en/stable/img/banner_og.png", + "installUrl": "https://jrnl.sh/en/stable/installation", "softwareVersion": "2.5" } From a6362a993c35a3facf7ad40618ae14490244f3a1 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Tue, 20 Apr 2021 02:24:47 +0000 Subject: [PATCH 072/215] Increment version to v2.8.1-beta --- jrnl/__version__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jrnl/__version__.py b/jrnl/__version__.py index d01f99f3..740e8abc 100644 --- a/jrnl/__version__.py +++ b/jrnl/__version__.py @@ -1 +1 @@ -__version__ = "v2.8" +__version__ = "v2.8.1-beta" diff --git a/pyproject.toml b/pyproject.toml index 56773289..8325128b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "jrnl" -version = "v2.8" +version = "v2.8.1-beta" description = "Collect your thoughts and notes without leaving the command line." authors = [ "jrnl contributors ", From f13a0b58491b0cf932d184e835cb3802de39f035 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Tue, 20 Apr 2021 02:26:27 +0000 Subject: [PATCH 073/215] Update changelog [ci skip] --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8765f5a4..ce61677e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ # Changelog -## [Unreleased](https://github.com/jrnl-org/jrnl/) +## [v2.8.1-beta](https://pypi.org/project/jrnl/v2.8.1-beta/) (2021-04-20) -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8...HEAD) +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8...v2.8.1-beta) **Fixed bugs:** From 0e9ae8ee8a9ddf5ae32ec7d24ee6493dbd3dfe92 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 24 Apr 2021 18:07:52 +0000 Subject: [PATCH 074/215] Increment version to v2.8.1 --- jrnl/__version__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jrnl/__version__.py b/jrnl/__version__.py index 740e8abc..51977ba3 100644 --- a/jrnl/__version__.py +++ b/jrnl/__version__.py @@ -1 +1 @@ -__version__ = "v2.8.1-beta" +__version__ = "v2.8.1" diff --git a/pyproject.toml b/pyproject.toml index 8325128b..46ff65ab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "jrnl" -version = "v2.8.1-beta" +version = "v2.8.1" description = "Collect your thoughts and notes without leaving the command line." authors = [ "jrnl contributors ", From e23909881a9420bc25c73622e6d430624956c66c Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 24 Apr 2021 18:09:15 +0000 Subject: [PATCH 075/215] Update changelog [ci skip] --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce61677e..1382c90d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,16 @@ # Changelog -## [v2.8.1-beta](https://pypi.org/project/jrnl/v2.8.1-beta/) (2021-04-20) +## [v2.8.1](https://pypi.org/project/jrnl/v2.8.1/) (2021-04-24) -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8...v2.8.1-beta) +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.1-beta...v2.8.1) **Fixed bugs:** -- Fancy format crashes on low linewrap values [\#1201](https://github.com/jrnl-org/jrnl/issues/1201) - More graceful handling of low linewrap values [\#1219](https://github.com/jrnl-org/jrnl/pull/1219) ([sriniv27](https://github.com/sriniv27)) **Documentation:** +- Update absolute URLs to preview images in metatags [\#1229](https://github.com/jrnl-org/jrnl/pull/1229) ([maebert](https://github.com/maebert)) - Docs: Add emacs as external editor to recipes [\#1220](https://github.com/jrnl-org/jrnl/pull/1220) ([mandarvaze](https://github.com/mandarvaze)) **Packaging:** From 305127137aea11c6a72ae453c238937c00c82b2c Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 24 Apr 2021 11:27:32 -0700 Subject: [PATCH 076/215] Remove `--version` from brew release workflow (#1233) Homebrew doesn't like explicitly declaring a version for a formula (it prefers to infer it from the url), and will throw an error on PRs. So, this removes that part of the workflow. --- .github/workflows/release.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 3e4987e9..5e0169c1 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -188,7 +188,6 @@ jobs: brew bump-formula-pr "${FORMULA_NAME}" --url $(jq ".releases[\"${PYPI_VERSION}\"][1].url" -r api_response.json) --sha256 $(jq ".releases[\"${PYPI_VERSION}\"][1].digests.sha256" -r api_response.json) - --version=$PYPI_VERSION --no-audit --write --force From 36db809588bcb134d79a25064670d37d8364369b Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 24 Apr 2021 18:28:59 +0000 Subject: [PATCH 077/215] Update changelog [ci skip] --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1382c90d..020a0069 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [Unreleased](https://github.com/jrnl-org/jrnl/) + +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.1...HEAD) + +**Build:** + +- Remove `--version` from brew release workflow [\#1233](https://github.com/jrnl-org/jrnl/pull/1233) ([wren](https://github.com/wren)) + ## [v2.8.1](https://pypi.org/project/jrnl/v2.8.1/) (2021-04-24) [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.1-beta...v2.8.1) From b66ce460b6bce3ba4ef598333630e86a3acbe5b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 8 May 2021 12:32:01 -0700 Subject: [PATCH 078/215] Bump pytest from 6.2.3 to 6.2.4 (#1240) Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.2.3 to 6.2.4. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/6.2.3...6.2.4) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 58769e8c..cfbc3c2f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -425,7 +425,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "pytest" -version = "6.2.3" +version = "6.2.4" description = "pytest: simple powerful testing with Python" category = "dev" optional = false @@ -855,8 +855,8 @@ pyparsing = [ {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pytest = [ - {file = "pytest-6.2.3-py3-none-any.whl", hash = "sha256:6ad9c7bdf517a808242b998ac20063c41532a570d088d77eec1ee12b0b5574bc"}, - {file = "pytest-6.2.3.tar.gz", hash = "sha256:671238a46e4df0f3498d1c3270e5deb9b32d25134c99b7d75370a68cfbe9b634"}, + {file = "pytest-6.2.4-py3-none-any.whl", hash = "sha256:91ef2131a9bd6be8f76f1f08eac5c5317221d6ad1e143ae03894b862e8976890"}, + {file = "pytest-6.2.4.tar.gz", hash = "sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b"}, ] python-dateutil = [ {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, From f99387b3e546225fc48e998a2a3a81067db5e8c8 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 8 May 2021 19:33:41 +0000 Subject: [PATCH 079/215] Update changelog [ci skip] --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 020a0069..05956cff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ - Remove `--version` from brew release workflow [\#1233](https://github.com/jrnl-org/jrnl/pull/1233) ([wren](https://github.com/wren)) +**Packaging:** + +- Bump pytest from 6.2.3 to 6.2.4 [\#1240](https://github.com/jrnl-org/jrnl/pull/1240) ([dependabot[bot]](https://github.com/apps/dependabot)) + ## [v2.8.1](https://pypi.org/project/jrnl/v2.8.1/) (2021-04-24) [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.1-beta...v2.8.1) From b38d765759b150e75c3f44b7429e2be59dec097e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 8 May 2021 12:39:00 -0700 Subject: [PATCH 080/215] Bump black from 20.8b1 to 21.5b0 (#1241) * Bump black from 20.8b1 to 21.5b0 Bumps [black](https://github.com/psf/black) from 20.8b1 to 21.5b0. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/master/CHANGES.md) - [Commits](https://github.com/psf/black/commits) Signed-off-by: dependabot[bot] * Run make format with latest version of black Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Micah Jerome Ellison --- jrnl/commands.py | 2 +- jrnl/exception.py | 2 +- jrnl/jrnl.py | 2 +- poetry.lock | 78 ++++++++++++++++++++++++----------------------- pyproject.toml | 2 +- 5 files changed, 44 insertions(+), 42 deletions(-) diff --git a/jrnl/commands.py b/jrnl/commands.py index 8473954e..07ca0767 100644 --- a/jrnl/commands.py +++ b/jrnl/commands.py @@ -87,7 +87,7 @@ def postconfig_encrypt(args, config, original_config, **kwargs): def postconfig_decrypt(args, config, original_config, **kwargs): - """ Decrypts into new file. If filename is not set, we encrypt the journal file itself. """ + """Decrypts into new file. If filename is not set, we encrypt the journal file itself.""" from .Journal import PlainJournal from .Journal import open_journal from .config import update_config diff --git a/jrnl/exception.py b/jrnl/exception.py index ac7cd0b2..cb6672d7 100644 --- a/jrnl/exception.py +++ b/jrnl/exception.py @@ -14,7 +14,7 @@ class UpgradeValidationException(Exception): class JrnlError(Exception): - """Common exceptions raised by jrnl. """ + """Common exceptions raised by jrnl.""" def __init__(self, error_type, **kwargs): self.error_type = error_type diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index cf2b3bbb..2d06115d 100644 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -214,7 +214,7 @@ def _get_editor_template(config, **kwargs): def _search_journal(args, journal, **kwargs): - """ Search the journal with the given args""" + """Search the journal with the given args""" if args.on_date: args.start_date = args.end_date = args.on_date diff --git a/poetry.lock b/poetry.lock index cfbc3c2f..25c20495 100644 --- a/poetry.lock +++ b/poetry.lock @@ -80,25 +80,26 @@ docs = ["sphinx (>=1.6)", "sphinx-bootstrap-theme (>=0.6)"] [[package]] name = "black" -version = "20.8b1" +version = "21.5b0" description = "The uncompromising code formatter." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.6.2" [package.dependencies] appdirs = "*" click = ">=7.1.2" mypy-extensions = ">=0.4.3" -pathspec = ">=0.6,<1" +pathspec = ">=0.8.1,<1" regex = ">=2020.1.8" toml = ">=0.10.1" -typed-ast = ">=1.4.0" -typing-extensions = ">=3.7.4" +typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\""} +typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} [package.extras] colorama = ["colorama (>=0.4.3)"] d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] +python2 = ["typed-ast (>=1.4.2)"] [[package]] name = "cffi" @@ -553,7 +554,7 @@ dev = ["py-make (>=0.1.0)", "twine", "argopt", "pydoc-markdown", "wheel"] [[package]] name = "typed-ast" -version = "1.4.1" +version = "1.4.3" description = "a fork of Python 2 and 3 ast modules with type comment support" category = "dev" optional = false @@ -618,7 +619,7 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake [metadata] lock-version = "1.1" python-versions = ">=3.7.0, <3.10" -content-hash = "1757c9f22bd1c3e2e4c6b7785d4c8e14a670334a21ab5de2137faf0fd10819b9" +content-hash = "564ac922fb9bc8c9691eebf4464f3827fa52cfd92d45853f714cdb36d6aa6a90" [metadata.files] ansiwrap = [ @@ -649,7 +650,8 @@ behave = [ {file = "behave-1.2.6.tar.gz", hash = "sha256:b9662327aa53294c1351b0a9c369093ccec1d21026f050c3bd9b3e5cccf81a86"}, ] black = [ - {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, + {file = "black-21.5b0-py3-none-any.whl", hash = "sha256:0e80435b8a88f383c9149ae89d671eb2095b72344b0fe8a1d61d2ff5110ed173"}, + {file = "black-21.5b0.tar.gz", hash = "sha256:9dc2042018ca10735366d944c2c12d9cad6dec74a3d5f679d09384ea185d9943"}, ] cffi = [ {file = "cffi-1.14.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ebb253464a5d0482b191274f1c8bf00e33f7e0b9c66405fbffc61ed2c839c775"}, @@ -1012,36 +1014,36 @@ tqdm = [ {file = "tqdm-4.54.1.tar.gz", hash = "sha256:38b658a3e4ecf9b4f6f8ff75ca16221ae3378b2e175d846b6b33ea3a20852cf5"}, ] typed-ast = [ - {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, - {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"}, - {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"}, - {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"}, - {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"}, - {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"}, - {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"}, - {file = "typed_ast-1.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:fcf135e17cc74dbfbc05894ebca928ffeb23d9790b3167a674921db19082401f"}, - {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"}, - {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"}, - {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"}, - {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"}, - {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"}, - {file = "typed_ast-1.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:f208eb7aff048f6bea9586e61af041ddf7f9ade7caed625742af423f6bae3298"}, - {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"}, - {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"}, - {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"}, - {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"}, - {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"}, - {file = "typed_ast-1.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7e4c9d7658aaa1fc80018593abdf8598bf91325af6af5cce4ce7c73bc45ea53d"}, - {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"}, - {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"}, - {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"}, - {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:92c325624e304ebf0e025d1224b77dd4e6393f18aab8d829b5b7e04afe9b7a2c"}, - {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d648b8e3bf2fe648745c8ffcee3db3ff903d0817a01a12dd6a6ea7a8f4889072"}, - {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:fac11badff8313e23717f3dada86a15389d0708275bddf766cca67a84ead3e91"}, - {file = "typed_ast-1.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:0d8110d78a5736e16e26213114a38ca35cb15b6515d535413b090bd50951556d"}, - {file = "typed_ast-1.4.1-cp39-cp39-win32.whl", hash = "sha256:b52ccf7cfe4ce2a1064b18594381bccf4179c2ecf7f513134ec2f993dd4ab395"}, - {file = "typed_ast-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:3742b32cf1c6ef124d57f95be609c473d7ec4c14d0090e5a5e05a15269fb4d0c"}, - {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, + {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"}, + {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"}, + {file = "typed_ast-1.4.3-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:1b3ead4a96c9101bef08f9f7d1217c096f31667617b58de957f690c92378b528"}, + {file = "typed_ast-1.4.3-cp35-cp35m-win32.whl", hash = "sha256:dde816ca9dac1d9c01dd504ea5967821606f02e510438120091b84e852367428"}, + {file = "typed_ast-1.4.3-cp35-cp35m-win_amd64.whl", hash = "sha256:777a26c84bea6cd934422ac2e3b78863a37017618b6e5c08f92ef69853e765d3"}, + {file = "typed_ast-1.4.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f8afcf15cc511ada719a88e013cec87c11aff7b91f019295eb4530f96fe5ef2f"}, + {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:52b1eb8c83f178ab787f3a4283f68258525f8d70f778a2f6dd54d3b5e5fb4341"}, + {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace"}, + {file = "typed_ast-1.4.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c190f0899e9f9f8b6b7863debfb739abcb21a5c054f911ca3596d12b8a4c4c7f"}, + {file = "typed_ast-1.4.3-cp36-cp36m-win32.whl", hash = "sha256:398e44cd480f4d2b7ee8d98385ca104e35c81525dd98c519acff1b79bdaac363"}, + {file = "typed_ast-1.4.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bff6ad71c81b3bba8fa35f0f1921fb24ff4476235a6e94a26ada2e54370e6da7"}, + {file = "typed_ast-1.4.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0fb71b8c643187d7492c1f8352f2c15b4c4af3f6338f21681d3681b3dc31a266"}, + {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:760ad187b1041a154f0e4d0f6aae3e40fdb51d6de16e5c99aedadd9246450e9e"}, + {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5feca99c17af94057417d744607b82dd0a664fd5e4ca98061480fd8b14b18d04"}, + {file = "typed_ast-1.4.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:95431a26309a21874005845c21118c83991c63ea800dd44843e42a916aec5899"}, + {file = "typed_ast-1.4.3-cp37-cp37m-win32.whl", hash = "sha256:aee0c1256be6c07bd3e1263ff920c325b59849dc95392a05f258bb9b259cf39c"}, + {file = "typed_ast-1.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9ad2c92ec681e02baf81fdfa056fe0d818645efa9af1f1cd5fd6f1bd2bdfd805"}, + {file = "typed_ast-1.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b36b4f3920103a25e1d5d024d155c504080959582b928e91cb608a65c3a49e1a"}, + {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:067a74454df670dcaa4e59349a2e5c81e567d8d65458d480a5b3dfecec08c5ff"}, + {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7538e495704e2ccda9b234b82423a4038f324f3a10c43bc088a1636180f11a41"}, + {file = "typed_ast-1.4.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:af3d4a73793725138d6b334d9d247ce7e5f084d96284ed23f22ee626a7b88e39"}, + {file = "typed_ast-1.4.3-cp38-cp38-win32.whl", hash = "sha256:f2362f3cb0f3172c42938946dbc5b7843c2a28aec307c49100c8b38764eb6927"}, + {file = "typed_ast-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:dd4a21253f42b8d2b48410cb31fe501d32f8b9fbeb1f55063ad102fe9c425e40"}, + {file = "typed_ast-1.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f328adcfebed9f11301eaedfa48e15bdece9b519fb27e6a8c01aa52a17ec31b3"}, + {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:2c726c276d09fc5c414693a2de063f521052d9ea7c240ce553316f70656c84d4"}, + {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:cae53c389825d3b46fb37538441f75d6aecc4174f615d048321b716df2757fb0"}, + {file = "typed_ast-1.4.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9574c6f03f685070d859e75c7f9eeca02d6933273b5e69572e5ff9d5e3931c3"}, + {file = "typed_ast-1.4.3-cp39-cp39-win32.whl", hash = "sha256:209596a4ec71d990d71d5e0d312ac935d86930e6eecff6ccc7007fe54d703808"}, + {file = "typed_ast-1.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:9c6d1a54552b5330bc657b7ef0eae25d00ba7ffe85d9ea8ae6540d2197a3788c"}, + {file = "typed_ast-1.4.3.tar.gz", hash = "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65"}, ] typing-extensions = [ {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"}, diff --git a/pyproject.toml b/pyproject.toml index 46ff65ab..95670898 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ tzlocal = ">2.0, <3.0" # https://github.com/regebro/tzlocal/blob/master/CHANGE [tool.poetry.dev-dependencies] behave = "^1.2" mkdocs = "^1.0" -black = {version = "^20.8b1",allow-prereleases = true} +black = {version = "^21.5b0",allow-prereleases = true} toml = ">=0.10" pyflakes = ">=2.2.0" pytest = ">=6.2" From c6815621df11d5bfd22aab6f0219399aa89ab198 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 8 May 2021 19:40:25 +0000 Subject: [PATCH 081/215] Update changelog [ci skip] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05956cff..e65cf3bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ **Packaging:** +- Bump black from 20.8b1 to 21.5b0 [\#1241](https://github.com/jrnl-org/jrnl/pull/1241) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump pytest from 6.2.3 to 6.2.4 [\#1240](https://github.com/jrnl-org/jrnl/pull/1240) ([dependabot[bot]](https://github.com/apps/dependabot)) ## [v2.8.1](https://pypi.org/project/jrnl/v2.8.1/) (2021-04-24) From 17c7f4c648e0427a3508278d04b299f7dfe06a38 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 29 May 2021 11:46:46 -0700 Subject: [PATCH 082/215] Bump black from 21.5b0 to 21.5b1 (#1244) Bumps [black](https://github.com/psf/black) from 21.5b0 to 21.5b1. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/commits) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 10 +++++----- pyproject.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index 25c20495..5cc5c163 100644 --- a/poetry.lock +++ b/poetry.lock @@ -80,7 +80,7 @@ docs = ["sphinx (>=1.6)", "sphinx-bootstrap-theme (>=0.6)"] [[package]] name = "black" -version = "21.5b0" +version = "21.5b1" description = "The uncompromising code formatter." category = "dev" optional = false @@ -98,7 +98,7 @@ typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} [package.extras] colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] +d = ["aiohttp (>=3.6.0)", "aiohttp-cors"] python2 = ["typed-ast (>=1.4.2)"] [[package]] @@ -619,7 +619,7 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake [metadata] lock-version = "1.1" python-versions = ">=3.7.0, <3.10" -content-hash = "564ac922fb9bc8c9691eebf4464f3827fa52cfd92d45853f714cdb36d6aa6a90" +content-hash = "7e44a55c0f4c1a504674d707acdf875d8f53fd2d9d30ed241a2dc8f2d6af8375" [metadata.files] ansiwrap = [ @@ -650,8 +650,8 @@ behave = [ {file = "behave-1.2.6.tar.gz", hash = "sha256:b9662327aa53294c1351b0a9c369093ccec1d21026f050c3bd9b3e5cccf81a86"}, ] black = [ - {file = "black-21.5b0-py3-none-any.whl", hash = "sha256:0e80435b8a88f383c9149ae89d671eb2095b72344b0fe8a1d61d2ff5110ed173"}, - {file = "black-21.5b0.tar.gz", hash = "sha256:9dc2042018ca10735366d944c2c12d9cad6dec74a3d5f679d09384ea185d9943"}, + {file = "black-21.5b1-py3-none-any.whl", hash = "sha256:8a60071a0043876a4ae96e6c69bd3a127dad2c1ca7c8083573eb82f92705d008"}, + {file = "black-21.5b1.tar.gz", hash = "sha256:23695358dbcb3deafe7f0a3ad89feee5999a46be5fec21f4f1d108be0bcdb3b1"}, ] cffi = [ {file = "cffi-1.14.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ebb253464a5d0482b191274f1c8bf00e33f7e0b9c66405fbffc61ed2c839c775"}, diff --git a/pyproject.toml b/pyproject.toml index 95670898..5eaf1fbc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ tzlocal = ">2.0, <3.0" # https://github.com/regebro/tzlocal/blob/master/CHANGE [tool.poetry.dev-dependencies] behave = "^1.2" mkdocs = "^1.0" -black = {version = "^21.5b0",allow-prereleases = true} +black = {version = "^21.5b1",allow-prereleases = true} toml = ">=0.10" pyflakes = ">=2.2.0" pytest = ">=6.2" From 104fa2cacaab6fe32e073a2f4100172dcb902241 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 29 May 2021 18:48:21 +0000 Subject: [PATCH 083/215] Update changelog [ci skip] --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e65cf3bb..6cd48883 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,17 @@ [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.1...HEAD) +**Implemented enhancements:** + +- Multiple entries with same timestamp should be grouped together [\#1247](https://github.com/jrnl-org/jrnl/issues/1247) + **Build:** - Remove `--version` from brew release workflow [\#1233](https://github.com/jrnl-org/jrnl/pull/1233) ([wren](https://github.com/wren)) **Packaging:** +- Bump black from 21.5b0 to 21.5b1 [\#1244](https://github.com/jrnl-org/jrnl/pull/1244) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump black from 20.8b1 to 21.5b0 [\#1241](https://github.com/jrnl-org/jrnl/pull/1241) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump pytest from 6.2.3 to 6.2.4 [\#1240](https://github.com/jrnl-org/jrnl/pull/1240) ([dependabot[bot]](https://github.com/apps/dependabot)) From 6fc252b2c73f9b9a87a85cc1290f45ba5f156b37 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Jun 2021 13:14:05 -0700 Subject: [PATCH 084/215] Bump black from 21.5b1 to 21.5b2 (#1254) Bumps [black](https://github.com/psf/black) from 21.5b1 to 21.5b2. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/commits) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 11 ++++++----- pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5cc5c163..238b977c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -80,7 +80,7 @@ docs = ["sphinx (>=1.6)", "sphinx-bootstrap-theme (>=0.6)"] [[package]] name = "black" -version = "21.5b1" +version = "21.5b2" description = "The uncompromising code formatter." category = "dev" optional = false @@ -98,8 +98,9 @@ typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} [package.extras] colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.6.0)", "aiohttp-cors"] +d = ["aiohttp (>=3.6.0)", "aiohttp-cors (>=0.4.0)"] python2 = ["typed-ast (>=1.4.2)"] +uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "cffi" @@ -619,7 +620,7 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake [metadata] lock-version = "1.1" python-versions = ">=3.7.0, <3.10" -content-hash = "7e44a55c0f4c1a504674d707acdf875d8f53fd2d9d30ed241a2dc8f2d6af8375" +content-hash = "4d9054a240b279da990b8038623d8b2025487ef37162f7f7ef4a4ff8cbae872b" [metadata.files] ansiwrap = [ @@ -650,8 +651,8 @@ behave = [ {file = "behave-1.2.6.tar.gz", hash = "sha256:b9662327aa53294c1351b0a9c369093ccec1d21026f050c3bd9b3e5cccf81a86"}, ] black = [ - {file = "black-21.5b1-py3-none-any.whl", hash = "sha256:8a60071a0043876a4ae96e6c69bd3a127dad2c1ca7c8083573eb82f92705d008"}, - {file = "black-21.5b1.tar.gz", hash = "sha256:23695358dbcb3deafe7f0a3ad89feee5999a46be5fec21f4f1d108be0bcdb3b1"}, + {file = "black-21.5b2-py3-none-any.whl", hash = "sha256:e5cf21ebdffc7a9b29d73912b6a6a9a4df4ce70220d523c21647da2eae0751ef"}, + {file = "black-21.5b2.tar.gz", hash = "sha256:1fc0e0a2c8ae7d269dfcf0c60a89afa299664f3e811395d40b1922dff8f854b5"}, ] cffi = [ {file = "cffi-1.14.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ebb253464a5d0482b191274f1c8bf00e33f7e0b9c66405fbffc61ed2c839c775"}, diff --git a/pyproject.toml b/pyproject.toml index 5eaf1fbc..8a46fe34 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ tzlocal = ">2.0, <3.0" # https://github.com/regebro/tzlocal/blob/master/CHANGE [tool.poetry.dev-dependencies] behave = "^1.2" mkdocs = "^1.0" -black = {version = "^21.5b1",allow-prereleases = true} +black = {version = "^21.5b2",allow-prereleases = true} toml = ">=0.10" pyflakes = ">=2.2.0" pytest = ">=6.2" From e84bb603eb66d2dc3e2531ad2b67cb7beba8556f Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 5 Jun 2021 13:15:17 -0700 Subject: [PATCH 085/215] Ensure that line endings in all py files are Linux style instead of Windows (#1250) --- tests/test_exception.py | 38 +++++++++++++++++------------------ tests/test_install.py | 26 ++++++++++++------------ tests/test_time.py | 44 ++++++++++++++++++++--------------------- 3 files changed, 54 insertions(+), 54 deletions(-) diff --git a/tests/test_exception.py b/tests/test_exception.py index 85eb77e9..1fee1982 100644 --- a/tests/test_exception.py +++ b/tests/test_exception.py @@ -1,19 +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. - """ - ) +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. + """ + ) diff --git a/tests/test_install.py b/tests/test_install.py index e24d3b9c..31ec150c 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -1,13 +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 +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 diff --git a/tests/test_time.py b/tests/test_time.py index 89f65cb7..c829c52b 100644 --- a/tests/test_time.py +++ b/tests/test_time.py @@ -1,22 +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) - ) +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) + ) From 5e87ff1ce696c5b59fb1389e7e45c20c90047781 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 5 Jun 2021 20:16:47 +0000 Subject: [PATCH 086/215] Update changelog [ci skip] --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cd48883..62d28c70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,9 +14,9 @@ **Packaging:** +- Bump black from 21.5b1 to 21.5b2 [\#1254](https://github.com/jrnl-org/jrnl/pull/1254) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump black from 21.5b0 to 21.5b1 [\#1244](https://github.com/jrnl-org/jrnl/pull/1244) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump black from 20.8b1 to 21.5b0 [\#1241](https://github.com/jrnl-org/jrnl/pull/1241) ([dependabot[bot]](https://github.com/apps/dependabot)) -- Bump pytest from 6.2.3 to 6.2.4 [\#1240](https://github.com/jrnl-org/jrnl/pull/1240) ([dependabot[bot]](https://github.com/apps/dependabot)) ## [v2.8.1](https://pypi.org/project/jrnl/v2.8.1/) (2021-04-24) From a9c539821f127c0bda93e35617858e3b73b717fe Mon Sep 17 00:00:00 2001 From: Ben Beasley Date: Sat, 3 Jul 2021 18:20:52 -0400 Subject: [PATCH 087/215] Remove useless shebangs and executable permissions (#1283) * Remove executable permissions from non-script files * Remove harmless-but-useless shebang lines --- docs_theme/index.html | 0 jrnl/DayOneJournal.py | 2 -- jrnl/Entry.py | 1 - jrnl/FolderJournal.py | 1 - jrnl/Journal.py | 1 - jrnl/__init__.py | 1 - jrnl/__main__.py | 1 - jrnl/cli.py | 1 - jrnl/color.py | 1 - jrnl/install.py | 1 - jrnl/plugins/__init__.py | 1 - jrnl/plugins/dates_exporter.py | 1 - jrnl/plugins/fancy_exporter.py | 1 - jrnl/plugins/jrnl_importer.py | 1 - jrnl/plugins/json_exporter.py | 1 - jrnl/plugins/markdown_exporter.py | 1 - jrnl/plugins/tag_exporter.py | 1 - jrnl/plugins/template_exporter.py | 1 - jrnl/plugins/text_exporter.py | 1 - jrnl/plugins/util.py | 1 - jrnl/plugins/xml_exporter.py | 1 - jrnl/plugins/yaml_exporter.py | 1 - 22 files changed, 22 deletions(-) mode change 100755 => 100644 docs_theme/index.html mode change 100755 => 100644 jrnl/Entry.py diff --git a/docs_theme/index.html b/docs_theme/index.html old mode 100755 new mode 100644 diff --git a/jrnl/DayOneJournal.py b/jrnl/DayOneJournal.py index 6e1b8345..61a60ca0 100644 --- a/jrnl/DayOneJournal.py +++ b/jrnl/DayOneJournal.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - from datetime import datetime import fnmatch import os diff --git a/jrnl/Entry.py b/jrnl/Entry.py old mode 100755 new mode 100644 index 67ba84f3..e227794f --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/FolderJournal.py b/jrnl/FolderJournal.py index e727cdf0..954a9436 100644 --- a/jrnl/FolderJournal.py +++ b/jrnl/FolderJournal.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # encoding: utf-8 # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/Journal.py b/jrnl/Journal.py index 4196571d..b889c0d3 100644 --- a/jrnl/Journal.py +++ b/jrnl/Journal.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/__init__.py b/jrnl/__init__.py index 8f4dc3ec..550d580f 100644 --- a/jrnl/__init__.py +++ b/jrnl/__init__.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/__main__.py b/jrnl/__main__.py index e977369f..49497161 100644 --- a/jrnl/__main__.py +++ b/jrnl/__main__.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/cli.py b/jrnl/cli.py index 93a7e899..6a1c6a0f 100644 --- a/jrnl/cli.py +++ b/jrnl/cli.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/color.py b/jrnl/color.py index 3bdd4149..691cce9c 100644 --- a/jrnl/color.py +++ b/jrnl/color.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python import re from string import punctuation from string import whitespace diff --git a/jrnl/install.py b/jrnl/install.py index db4c0fba..b0ae2aa1 100644 --- a/jrnl/install.py +++ b/jrnl/install.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/plugins/__init__.py b/jrnl/plugins/__init__.py index 3eb4d5a2..da6199fb 100644 --- a/jrnl/plugins/__init__.py +++ b/jrnl/plugins/__init__.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # encoding: utf-8 # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/plugins/dates_exporter.py b/jrnl/plugins/dates_exporter.py index d11e527c..e032b652 100644 --- a/jrnl/plugins/dates_exporter.py +++ b/jrnl/plugins/dates_exporter.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # encoding: utf-8 # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/plugins/fancy_exporter.py b/jrnl/plugins/fancy_exporter.py index 15efc19b..2cb27eca 100644 --- a/jrnl/plugins/fancy_exporter.py +++ b/jrnl/plugins/fancy_exporter.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # encoding: utf-8 # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/plugins/jrnl_importer.py b/jrnl/plugins/jrnl_importer.py index af5ea6ce..214fc70b 100644 --- a/jrnl/plugins/jrnl_importer.py +++ b/jrnl/plugins/jrnl_importer.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # encoding: utf-8 # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/plugins/json_exporter.py b/jrnl/plugins/json_exporter.py index dd07b0ce..666d9a3d 100644 --- a/jrnl/plugins/json_exporter.py +++ b/jrnl/plugins/json_exporter.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # encoding: utf-8 # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/plugins/markdown_exporter.py b/jrnl/plugins/markdown_exporter.py index 693f2fa5..11f748b6 100644 --- a/jrnl/plugins/markdown_exporter.py +++ b/jrnl/plugins/markdown_exporter.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # encoding: utf-8 # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/plugins/tag_exporter.py b/jrnl/plugins/tag_exporter.py index bc3736eb..1153fa01 100644 --- a/jrnl/plugins/tag_exporter.py +++ b/jrnl/plugins/tag_exporter.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # encoding: utf-8 # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/plugins/template_exporter.py b/jrnl/plugins/template_exporter.py index af081f8c..d2e5ce3e 100644 --- a/jrnl/plugins/template_exporter.py +++ b/jrnl/plugins/template_exporter.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # encoding: utf-8 # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/plugins/text_exporter.py b/jrnl/plugins/text_exporter.py index 7714606c..c9eaaf14 100644 --- a/jrnl/plugins/text_exporter.py +++ b/jrnl/plugins/text_exporter.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # encoding: utf-8 # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/plugins/util.py b/jrnl/plugins/util.py index 04159ca4..ae49a2a8 100644 --- a/jrnl/plugins/util.py +++ b/jrnl/plugins/util.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # encoding: utf-8 # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/plugins/xml_exporter.py b/jrnl/plugins/xml_exporter.py index b9467912..9901f4b7 100644 --- a/jrnl/plugins/xml_exporter.py +++ b/jrnl/plugins/xml_exporter.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # encoding: utf-8 # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html diff --git a/jrnl/plugins/yaml_exporter.py b/jrnl/plugins/yaml_exporter.py index 7716c6c1..887fdaf1 100644 --- a/jrnl/plugins/yaml_exporter.py +++ b/jrnl/plugins/yaml_exporter.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # encoding: utf-8 # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html From ace6b8004c44a5db66c90f82e1e68015b2b7be8b Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 3 Jul 2021 22:22:37 +0000 Subject: [PATCH 088/215] Update changelog [ci skip] --- CHANGELOG.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62d28c70..c8f71a70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,9 @@ [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.1...HEAD) -**Implemented enhancements:** - -- Multiple entries with same timestamp should be grouped together [\#1247](https://github.com/jrnl-org/jrnl/issues/1247) - **Build:** +- Remove useless shebangs and executable permissions [\#1283](https://github.com/jrnl-org/jrnl/pull/1283) ([musicinmybrain](https://github.com/musicinmybrain)) - Remove `--version` from brew release workflow [\#1233](https://github.com/jrnl-org/jrnl/pull/1233) ([wren](https://github.com/wren)) **Packaging:** @@ -17,6 +14,7 @@ - Bump black from 21.5b1 to 21.5b2 [\#1254](https://github.com/jrnl-org/jrnl/pull/1254) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump black from 21.5b0 to 21.5b1 [\#1244](https://github.com/jrnl-org/jrnl/pull/1244) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump black from 20.8b1 to 21.5b0 [\#1241](https://github.com/jrnl-org/jrnl/pull/1241) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump pytest from 6.2.3 to 6.2.4 [\#1240](https://github.com/jrnl-org/jrnl/pull/1240) ([dependabot[bot]](https://github.com/apps/dependabot)) ## [v2.8.1](https://pypi.org/project/jrnl/v2.8.1/) (2021-04-24) From 1390493a29e734f6507407137da4d4dd0f22a84c Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Mon, 28 Dec 2020 09:45:22 -0800 Subject: [PATCH 089/215] Install pytest-bdd (which will eventually replace behave) - Copy over the current tests from behave into the new directory that pytest-bdd will use them in Co-authored-by: Micah Jerome Ellison --- __init__.py | 3 + poetry.lock | 639 ++++++++---------- pyproject.toml | 4 + tests/features/build.feature | 8 + tests/features/configs/basic_dayone.yaml | 17 + tests/features/configs/basic_encrypted.yaml | 17 + tests/features/configs/basic_folder.yaml | 17 + tests/features/configs/basic_onefile.yaml | 17 + tests/features/configs/brackets.yaml | 12 + tests/features/configs/bug153.yaml | 17 + tests/features/configs/bug343.yaml | 13 + tests/features/configs/bug780.yaml | 12 + tests/features/configs/dayone.yaml | 12 + tests/features/configs/dayone_empty.yaml | 17 + tests/features/configs/deletion.yaml | 12 + tests/features/configs/deletion_filters.yaml | 12 + tests/features/configs/editor-args.yaml | 12 + tests/features/configs/editor.yaml | 12 + .../features/configs/editor_empty_folder.yaml | 12 + tests/features/configs/editor_encrypted.yaml | 17 + .../configs/editor_markdown_extension.yaml | 18 + tests/features/configs/empty_folder.yaml | 12 + tests/features/configs/encrypted.yaml | 12 + tests/features/configs/encrypted_old.json | 13 + tests/features/configs/encrypted_old.yaml | 11 + tests/features/configs/format_md.yaml | 19 + tests/features/configs/format_text.yaml | 19 + tests/features/configs/invalid_color.yaml | 17 + .../features/configs/little_endian_dates.yaml | 12 + .../configs/markdown-headings-335.yaml | 17 + tests/features/configs/missing_directory.yaml | 17 + tests/features/configs/missing_journal.yaml | 17 + .../features/configs/mostlyreadabledates.yaml | 12 + tests/features/configs/multiline-tags.yaml | 17 + tests/features/configs/multiline.yaml | 17 + tests/features/configs/multiple.yaml | 18 + tests/features/configs/no_colors.yaml | 12 + tests/features/configs/simple.yaml | 18 + tests/features/configs/tags-216.yaml | 17 + tests/features/configs/tags-237.yaml | 17 + tests/features/configs/tags.yaml | 17 + tests/features/configs/unreadabledates.yaml | 17 + tests/features/configs/upgrade_from_195.json | 11 + .../upgrade_from_195_little_endian_dates.json | 11 + ...om_195_with_missing_encrypted_journal.json | 11 + ...upgrade_from_195_with_missing_journal.json | 11 + tests/features/core.feature | 7 + tests/features/data/configs/basic_dayone.yaml | 17 + .../data/configs/basic_encrypted.yaml | 17 + tests/features/data/configs/basic_folder.yaml | 17 + .../features/data/configs/basic_onefile.yaml | 17 + tests/features/data/configs/brackets.yaml | 12 + tests/features/data/configs/bug153.yaml | 17 + tests/features/data/configs/bug343.yaml | 13 + tests/features/data/configs/bug780.yaml | 12 + tests/features/data/configs/dayone.yaml | 12 + tests/features/data/configs/dayone_empty.yaml | 17 + tests/features/data/configs/deletion.yaml | 12 + .../data/configs/deletion_filters.yaml | 12 + tests/features/data/configs/editor-args.yaml | 12 + tests/features/data/configs/editor.yaml | 12 + .../data/configs/editor_empty_folder.yaml | 12 + .../data/configs/editor_encrypted.yaml | 17 + tests/features/data/configs/empty_folder.yaml | 12 + tests/features/data/configs/encrypted.yaml | 12 + .../features/data/configs/encrypted_old.json | 13 + .../features/data/configs/encrypted_old.yaml | 11 + tests/features/data/configs/format_md.yaml | 19 + tests/features/data/configs/format_text.yaml | 19 + .../features/data/configs/invalid_color.yaml | 17 + .../data/configs/little_endian_dates.yaml | 12 + .../data/configs/markdown-headings-335.yaml | 17 + .../data/configs/missing_directory.yaml | 17 + .../data/configs/missing_journal.yaml | 17 + .../data/configs/mostlyreadabledates.yaml | 12 + .../features/data/configs/multiline-tags.yaml | 17 + tests/features/data/configs/multiline.yaml | 17 + tests/features/data/configs/multiple.yaml | 18 + tests/features/data/configs/no_colors.yaml | 12 + tests/features/data/configs/simple.yaml | 17 + tests/features/data/configs/tags-216.yaml | 17 + tests/features/data/configs/tags-237.yaml | 17 + tests/features/data/configs/tags.yaml | 17 + .../data/configs/unreadabledates.yaml | 17 + .../data/configs/upgrade_from_195.json | 11 + .../upgrade_from_195_little_endian_dates.json | 11 + ...om_195_with_missing_encrypted_journal.json | 11 + ...upgrade_from_195_with_missing_journal.json | 11 + .../D04D335AFED711EABA18FAFFC2100C3D.doentry | 53 ++ .../FC8A86CAFED711EA8892FAFFC2100C3D.doentry | 55 ++ .../FD8ABC8EFED711EABC35FAFFC2100C3D.doentry | 44 ++ .../data/journals/basic_encrypted.journal | 1 + .../data/journals/basic_folder/2020/08/29.txt | 19 + .../data/journals/basic_folder/2020/08/31.txt | 23 + .../data/journals/basic_folder/2020/09/24.txt | 11 + .../data/journals/basic_onefile.journal | 58 ++ tests/features/data/journals/brackets.journal | 2 + .../B40EE704E15846DE8D45C44118A4D511.doentry | 56 ++ .../B40EE704E15846DE8D45C44118A4D512.doentry | 52 ++ .../48A25033B34047C591160A4480197D8B.doentry | 33 + .../044F3747A38546168B572C2E3F217FA2.doentry | 34 + .../0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry | 46 ++ .../422BC895507944A291E6FC44FC6B8BFC.doentry | 31 + .../4BB1F46946AD439996C9B59DE7C4DDC1.doentry | 29 + .../dayone_empty.dayone/entries/empty.txt | 1 + tests/features/data/journals/deletion.journal | 5 + .../data/journals/deletion_filters.journal | 14 + .../features/data/journals/empty_folder/empty | 1 + .../features/data/journals/encrypted.journal | 1 + .../journals/encrypted_jrnl-1-9-5.journal | Bin 0 -> 128 bytes .../data/journals/little_endian_dates.journal | 5 + .../journals/markdown-headings-335.journal | 42 ++ .../data/journals/mostlyreadabledates.journal | 8 + .../data/journals/multiline-tags.journal | 7 + .../features/data/journals/multiline.journal | 5 + tests/features/data/journals/simple.journal | 5 + .../data/journals/simple_jrnl-1-9-5.journal | 13 + ...ple_jrnl-1-9-5_little_endian_dates.journal | 13 + tests/features/data/journals/tags-216.journal | 2 + tests/features/data/journals/tags-237.journal | 3 + tests/features/data/journals/tags.journal | 8 + .../data/journals/unreadabledates.journal | 5 + tests/features/data/journals/work.journal | 0 tests/features/data/templates/sample.template | 19 + tests/features/datetime.feature | 155 +++++ tests/features/delete.feature | 229 +++++++ tests/features/encrypt.feature | 35 + tests/features/environment.py | 0 tests/features/file_storage.feature | 56 ++ tests/features/format.feature | 579 ++++++++++++++++ tests/features/import.feature | 93 +++ .../D04D335AFED711EABA18FAFFC2100C3D.doentry | 53 ++ .../FC8A86CAFED711EA8892FAFFC2100C3D.doentry | 55 ++ .../FD8ABC8EFED711EABC35FAFFC2100C3D.doentry | 44 ++ .../features/journals/basic_encrypted.journal | 1 + .../journals/basic_folder/2020/08/29.txt | 19 + .../journals/basic_folder/2020/08/31.txt | 23 + .../journals/basic_folder/2020/09/24.txt | 11 + tests/features/journals/basic_onefile.journal | 58 ++ tests/features/journals/brackets.journal | 2 + .../B40EE704E15846DE8D45C44118A4D511.doentry | 56 ++ .../B40EE704E15846DE8D45C44118A4D512.doentry | 52 ++ .../48A25033B34047C591160A4480197D8B.doentry | 33 + .../044F3747A38546168B572C2E3F217FA2.doentry | 34 + .../0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry | 46 ++ .../422BC895507944A291E6FC44FC6B8BFC.doentry | 31 + .../4BB1F46946AD439996C9B59DE7C4DDC1.doentry | 29 + .../dayone_empty.dayone/entries/empty.txt | 1 + tests/features/journals/deletion.journal | 5 + .../journals/deletion_filters.journal | 14 + tests/features/journals/empty_folder/empty | 1 + tests/features/journals/encrypted.journal | 1 + .../journals/encrypted_jrnl-1-9-5.journal | Bin 0 -> 128 bytes .../journals/little_endian_dates.journal | 5 + .../journals/markdown-headings-335.journal | 42 ++ .../journals/mostlyreadabledates.journal | 8 + .../features/journals/multiline-tags.journal | 7 + tests/features/journals/multiline.journal | 5 + tests/features/journals/simple.journal | 5 + .../journals/simple_jrnl-1-9-5.journal | 13 + ...ple_jrnl-1-9-5_little_endian_dates.journal | 13 + tests/features/journals/tags-216.journal | 2 + tests/features/journals/tags-237.journal | 3 + tests/features/journals/tags.journal | 8 + .../features/journals/unreadabledates.journal | 5 + tests/features/journals/work.journal | 0 tests/features/multiple_journals.feature | 65 ++ tests/features/password.feature | 116 ++++ tests/features/search.feature | 318 +++++++++ tests/features/star.feature | 35 + tests/features/tag.feature | 53 ++ tests/features/templates/extension.md | 0 tests/features/upgrade.feature | 71 ++ tests/features/write.feature | 216 ++++++ tests/step_defs/__init__.py | 3 + tests/step_defs/conftest.py | 111 +++ tests/step_defs/test_features.py | 3 + 177 files changed, 5065 insertions(+), 340 deletions(-) create mode 100644 __init__.py create mode 100644 tests/features/build.feature create mode 100644 tests/features/configs/basic_dayone.yaml create mode 100644 tests/features/configs/basic_encrypted.yaml create mode 100644 tests/features/configs/basic_folder.yaml create mode 100644 tests/features/configs/basic_onefile.yaml create mode 100644 tests/features/configs/brackets.yaml create mode 100644 tests/features/configs/bug153.yaml create mode 100644 tests/features/configs/bug343.yaml create mode 100644 tests/features/configs/bug780.yaml create mode 100644 tests/features/configs/dayone.yaml create mode 100644 tests/features/configs/dayone_empty.yaml create mode 100644 tests/features/configs/deletion.yaml create mode 100644 tests/features/configs/deletion_filters.yaml create mode 100644 tests/features/configs/editor-args.yaml create mode 100644 tests/features/configs/editor.yaml create mode 100644 tests/features/configs/editor_empty_folder.yaml create mode 100644 tests/features/configs/editor_encrypted.yaml create mode 100644 tests/features/configs/editor_markdown_extension.yaml create mode 100644 tests/features/configs/empty_folder.yaml create mode 100644 tests/features/configs/encrypted.yaml create mode 100644 tests/features/configs/encrypted_old.json create mode 100644 tests/features/configs/encrypted_old.yaml create mode 100644 tests/features/configs/format_md.yaml create mode 100644 tests/features/configs/format_text.yaml create mode 100644 tests/features/configs/invalid_color.yaml create mode 100644 tests/features/configs/little_endian_dates.yaml create mode 100644 tests/features/configs/markdown-headings-335.yaml create mode 100644 tests/features/configs/missing_directory.yaml create mode 100644 tests/features/configs/missing_journal.yaml create mode 100644 tests/features/configs/mostlyreadabledates.yaml create mode 100644 tests/features/configs/multiline-tags.yaml create mode 100644 tests/features/configs/multiline.yaml create mode 100644 tests/features/configs/multiple.yaml create mode 100644 tests/features/configs/no_colors.yaml create mode 100644 tests/features/configs/simple.yaml create mode 100644 tests/features/configs/tags-216.yaml create mode 100644 tests/features/configs/tags-237.yaml create mode 100644 tests/features/configs/tags.yaml create mode 100644 tests/features/configs/unreadabledates.yaml create mode 100644 tests/features/configs/upgrade_from_195.json create mode 100644 tests/features/configs/upgrade_from_195_little_endian_dates.json create mode 100644 tests/features/configs/upgrade_from_195_with_missing_encrypted_journal.json create mode 100644 tests/features/configs/upgrade_from_195_with_missing_journal.json create mode 100644 tests/features/core.feature create mode 100644 tests/features/data/configs/basic_dayone.yaml create mode 100644 tests/features/data/configs/basic_encrypted.yaml create mode 100644 tests/features/data/configs/basic_folder.yaml create mode 100644 tests/features/data/configs/basic_onefile.yaml create mode 100644 tests/features/data/configs/brackets.yaml create mode 100644 tests/features/data/configs/bug153.yaml create mode 100644 tests/features/data/configs/bug343.yaml create mode 100644 tests/features/data/configs/bug780.yaml create mode 100644 tests/features/data/configs/dayone.yaml create mode 100644 tests/features/data/configs/dayone_empty.yaml create mode 100644 tests/features/data/configs/deletion.yaml create mode 100644 tests/features/data/configs/deletion_filters.yaml create mode 100644 tests/features/data/configs/editor-args.yaml create mode 100644 tests/features/data/configs/editor.yaml create mode 100644 tests/features/data/configs/editor_empty_folder.yaml create mode 100644 tests/features/data/configs/editor_encrypted.yaml create mode 100644 tests/features/data/configs/empty_folder.yaml create mode 100644 tests/features/data/configs/encrypted.yaml create mode 100644 tests/features/data/configs/encrypted_old.json create mode 100644 tests/features/data/configs/encrypted_old.yaml create mode 100644 tests/features/data/configs/format_md.yaml create mode 100644 tests/features/data/configs/format_text.yaml create mode 100644 tests/features/data/configs/invalid_color.yaml create mode 100644 tests/features/data/configs/little_endian_dates.yaml create mode 100644 tests/features/data/configs/markdown-headings-335.yaml create mode 100644 tests/features/data/configs/missing_directory.yaml create mode 100644 tests/features/data/configs/missing_journal.yaml create mode 100644 tests/features/data/configs/mostlyreadabledates.yaml create mode 100644 tests/features/data/configs/multiline-tags.yaml create mode 100644 tests/features/data/configs/multiline.yaml create mode 100644 tests/features/data/configs/multiple.yaml create mode 100644 tests/features/data/configs/no_colors.yaml create mode 100644 tests/features/data/configs/simple.yaml create mode 100644 tests/features/data/configs/tags-216.yaml create mode 100644 tests/features/data/configs/tags-237.yaml create mode 100644 tests/features/data/configs/tags.yaml create mode 100644 tests/features/data/configs/unreadabledates.yaml create mode 100644 tests/features/data/configs/upgrade_from_195.json create mode 100644 tests/features/data/configs/upgrade_from_195_little_endian_dates.json create mode 100644 tests/features/data/configs/upgrade_from_195_with_missing_encrypted_journal.json create mode 100644 tests/features/data/configs/upgrade_from_195_with_missing_journal.json create mode 100644 tests/features/data/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry create mode 100644 tests/features/data/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry create mode 100644 tests/features/data/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry create mode 100644 tests/features/data/journals/basic_encrypted.journal create mode 100644 tests/features/data/journals/basic_folder/2020/08/29.txt create mode 100644 tests/features/data/journals/basic_folder/2020/08/31.txt create mode 100644 tests/features/data/journals/basic_folder/2020/09/24.txt create mode 100644 tests/features/data/journals/basic_onefile.journal create mode 100644 tests/features/data/journals/brackets.journal create mode 100644 tests/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry create mode 100644 tests/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry create mode 100644 tests/features/data/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry create mode 100644 tests/features/data/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry create mode 100644 tests/features/data/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry create mode 100644 tests/features/data/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry create mode 100644 tests/features/data/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry create mode 100644 tests/features/data/journals/dayone_empty.dayone/entries/empty.txt create mode 100644 tests/features/data/journals/deletion.journal create mode 100644 tests/features/data/journals/deletion_filters.journal create mode 100644 tests/features/data/journals/empty_folder/empty create mode 100644 tests/features/data/journals/encrypted.journal create mode 100644 tests/features/data/journals/encrypted_jrnl-1-9-5.journal create mode 100644 tests/features/data/journals/little_endian_dates.journal create mode 100644 tests/features/data/journals/markdown-headings-335.journal create mode 100644 tests/features/data/journals/mostlyreadabledates.journal create mode 100644 tests/features/data/journals/multiline-tags.journal create mode 100644 tests/features/data/journals/multiline.journal create mode 100644 tests/features/data/journals/simple.journal create mode 100644 tests/features/data/journals/simple_jrnl-1-9-5.journal create mode 100644 tests/features/data/journals/simple_jrnl-1-9-5_little_endian_dates.journal create mode 100644 tests/features/data/journals/tags-216.journal create mode 100644 tests/features/data/journals/tags-237.journal create mode 100644 tests/features/data/journals/tags.journal create mode 100644 tests/features/data/journals/unreadabledates.journal create mode 100644 tests/features/data/journals/work.journal create mode 100644 tests/features/data/templates/sample.template create mode 100644 tests/features/datetime.feature create mode 100644 tests/features/delete.feature create mode 100644 tests/features/encrypt.feature create mode 100644 tests/features/environment.py create mode 100644 tests/features/file_storage.feature create mode 100644 tests/features/format.feature create mode 100644 tests/features/import.feature create mode 100644 tests/features/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry create mode 100644 tests/features/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry create mode 100644 tests/features/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry create mode 100644 tests/features/journals/basic_encrypted.journal create mode 100644 tests/features/journals/basic_folder/2020/08/29.txt create mode 100644 tests/features/journals/basic_folder/2020/08/31.txt create mode 100644 tests/features/journals/basic_folder/2020/09/24.txt create mode 100644 tests/features/journals/basic_onefile.journal create mode 100644 tests/features/journals/brackets.journal create mode 100644 tests/features/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry create mode 100644 tests/features/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry create mode 100644 tests/features/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry create mode 100644 tests/features/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry create mode 100644 tests/features/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry create mode 100644 tests/features/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry create mode 100644 tests/features/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry create mode 100644 tests/features/journals/dayone_empty.dayone/entries/empty.txt create mode 100644 tests/features/journals/deletion.journal create mode 100644 tests/features/journals/deletion_filters.journal create mode 100644 tests/features/journals/empty_folder/empty create mode 100644 tests/features/journals/encrypted.journal create mode 100644 tests/features/journals/encrypted_jrnl-1-9-5.journal create mode 100644 tests/features/journals/little_endian_dates.journal create mode 100644 tests/features/journals/markdown-headings-335.journal create mode 100644 tests/features/journals/mostlyreadabledates.journal create mode 100644 tests/features/journals/multiline-tags.journal create mode 100644 tests/features/journals/multiline.journal create mode 100644 tests/features/journals/simple.journal create mode 100644 tests/features/journals/simple_jrnl-1-9-5.journal create mode 100644 tests/features/journals/simple_jrnl-1-9-5_little_endian_dates.journal create mode 100644 tests/features/journals/tags-216.journal create mode 100644 tests/features/journals/tags-237.journal create mode 100644 tests/features/journals/tags.journal create mode 100644 tests/features/journals/unreadabledates.journal create mode 100644 tests/features/journals/work.journal create mode 100644 tests/features/multiple_journals.feature create mode 100644 tests/features/password.feature create mode 100644 tests/features/search.feature create mode 100644 tests/features/star.feature create mode 100644 tests/features/tag.feature create mode 100644 tests/features/templates/extension.md create mode 100644 tests/features/upgrade.feature create mode 100644 tests/features/write.feature create mode 100644 tests/step_defs/__init__.py create mode 100644 tests/step_defs/conftest.py create mode 100644 tests/step_defs/test_features.py diff --git a/__init__.py b/__init__.py new file mode 100644 index 00000000..46468510 --- /dev/null +++ b/__init__.py @@ -0,0 +1,3 @@ +import sys + +sys.path.append("..") diff --git a/poetry.lock b/poetry.lock index 238b977c..e999d3af 100644 --- a/poetry.lock +++ b/poetry.lock @@ -19,14 +19,14 @@ python-versions = "*" [[package]] name = "argcomplete" -version = "1.12.2" +version = "1.12.3" description = "Bash tab completion for argparse" category = "dev" optional = false python-versions = "*" [package.dependencies] -importlib-metadata = {version = ">=0.23,<4", markers = "python_version == \"3.7\""} +importlib-metadata = {version = ">=0.23,<5", markers = "python_version == \"3.7\""} [package.extras] test = ["coverage", "flake8", "pexpect", "wheel"] @@ -49,17 +49,17 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" -version = "20.3.0" +version = "21.2.0" description = "Classes Without Boilerplate" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"] -docs = ["furo", "sphinx", "zope.interface"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"] +docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"] [[package]] name = "behave" @@ -80,7 +80,7 @@ docs = ["sphinx (>=1.6)", "sphinx-bootstrap-theme (>=0.6)"] [[package]] name = "black" -version = "21.5b2" +version = "21.6b0" description = "The uncompromising code formatter." category = "dev" optional = false @@ -104,7 +104,7 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "cffi" -version = "1.14.4" +version = "1.14.5" description = "Foreign Function Interface for Python calling C code." category = "main" optional = false @@ -115,11 +115,15 @@ pycparser = "*" [[package]] name = "click" -version = "7.1.2" +version = "8.0.1" description = "Composable command line interface toolkit" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.6" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "colorama" @@ -149,16 +153,30 @@ ssh = ["bcrypt (>=3.1.5)"] test = ["pytest (>=6.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] [[package]] -name = "future" -version = "0.18.2" -description = "Clean single-source support for Python 3 and 2" +name = "ghp-import" +version = "2.0.1" +description = "Copy your docs directly to the gh-pages branch." category = "dev" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "*" + +[package.dependencies] +python-dateutil = ">=2.8.1" + +[package.extras] +dev = ["twine", "markdown", "flake8"] + +[[package]] +name = "glob2" +version = "0.7" +description = "Version of the glob module that can capture patterns and supports recursive wildcards" +category = "dev" +optional = false +python-versions = "*" [[package]] name = "importlib-metadata" -version = "3.7.2" +version = "4.5.0" description = "Read metadata from Python packages" category = "main" optional = false @@ -170,7 +188,7 @@ zipp = ">=0.5" [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" @@ -193,25 +211,17 @@ test = ["pytest", "pytest-trio", "pytest-asyncio", "testpath", "trio"] [[package]] name = "jinja2" -version = "2.11.2" +version = "3.0.1" description = "A very fast and expressive template engine." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.6" [package.dependencies] -MarkupSafe = ">=0.23" +MarkupSafe = ">=2.0" [package.extras] -i18n = ["Babel (>=0.8)"] - -[[package]] -name = "joblib" -version = "0.17.0" -description = "Lightweight pipelining: using Python functions as pipeline jobs." -category = "dev" -optional = false -python-versions = ">=3.6" +i18n = ["Babel (>=2.7)"] [[package]] name = "keyring" @@ -232,36 +242,23 @@ docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-black (>=0.3.7)", "pytest-mypy"] [[package]] -name = "livereload" -version = "2.6.3" -description = "Python LiveReload is an awesome tool for web developers" +name = "mako" +version = "1.1.4" +description = "A super-fast templating language that borrows the best ideas from the existing templating languages." category = "dev" optional = false -python-versions = "*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] -six = "*" -tornado = {version = "*", markers = "python_version > \"2.7\""} - -[[package]] -name = "lunr" -version = "0.5.8" -description = "A Python implementation of Lunr.js" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -future = ">=0.16.0" -nltk = {version = ">=3.2.5", optional = true, markers = "python_version > \"2.7\" and extra == \"languages\""} -six = ">=1.11.0" +MarkupSafe = ">=0.9.2" [package.extras] -languages = ["nltk (>=3.2.5,<3.5)", "nltk (>=3.2.5)"] +babel = ["babel"] +lingua = ["lingua"] [[package]] name = "markdown" -version = "3.3.3" +version = "3.3.4" description = "Python implementation of Markdown." category = "dev" optional = false @@ -275,28 +272,42 @@ testing = ["coverage", "pyyaml"] [[package]] name = "markupsafe" -version = "1.1.1" +version = "2.0.1" description = "Safely add untrusted strings to HTML/XML markup." category = "dev" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +python-versions = ">=3.6" + +[[package]] +name = "mergedeep" +version = "1.3.4" +description = "A deep merge function for 🐍." +category = "dev" +optional = false +python-versions = ">=3.6" [[package]] name = "mkdocs" -version = "1.1.2" +version = "1.2.1" description = "Project documentation with Markdown." category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" [package.dependencies] click = ">=3.3" +ghp-import = ">=1.0" +importlib-metadata = ">=3.10" Jinja2 = ">=2.10.1" -livereload = ">=2.5.1" -lunr = {version = "0.5.8", extras = ["languages"]} Markdown = ">=3.2.1" +mergedeep = ">=1.3.4" +packaging = ">=20.5" PyYAML = ">=3.10" -tornado = ">=5.0" +pyyaml-env-tag = ">=0.1" +watchdog = ">=2.0" + +[package.extras] +i18n = ["babel (>=2.9.0)"] [[package]] name = "mypy-extensions" @@ -306,31 +317,9 @@ category = "dev" optional = false python-versions = "*" -[[package]] -name = "nltk" -version = "3.5" -description = "Natural Language Toolkit" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -click = "*" -joblib = "*" -regex = "*" -tqdm = "*" - -[package.extras] -all = ["requests", "numpy", "python-crfsuite", "scikit-learn", "twython", "pyparsing", "scipy", "matplotlib", "gensim"] -corenlp = ["requests"] -machine_learning = ["gensim", "numpy", "python-crfsuite", "scikit-learn", "scipy"] -plot = ["matplotlib"] -tgrep = ["pyparsing"] -twitter = ["twython"] - [[package]] name = "packaging" -version = "20.8" +version = "20.9" description = "Core utilities for Python packages" category = "dev" optional = false @@ -341,7 +330,7 @@ pyparsing = ">=2.0.2" [[package]] name = "parse" -version = "1.18.0" +version = "1.19.0" description = "parse() is the opposite of format()" category = "dev" optional = false @@ -447,6 +436,23 @@ toml = "*" [package.extras] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +[[package]] +name = "pytest-bdd" +version = "4.0.2" +description = "BDD for pytest" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +glob2 = "*" +Mako = "*" +parse = "*" +parse-type = "*" +py = "*" +pytest = ">=4.3" +six = ">=1.9.0" + [[package]] name = "python-dateutil" version = "2.8.1" @@ -490,9 +496,20 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +description = "A custom YAML tag for referencing environment variables in YAML files. " +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pyyaml = "*" + [[package]] name = "regex" -version = "2020.11.13" +version = "2021.4.4" description = "Alternative regular expression module, to replace re." category = "dev" optional = false @@ -500,7 +517,7 @@ python-versions = "*" [[package]] name = "secretstorage" -version = "3.3.0" +version = "3.3.1" description = "Python bindings to FreeDesktop.org Secret Service API" category = "main" optional = false @@ -512,7 +529,7 @@ jeepney = ">=0.6" [[package]] name = "six" -version = "1.15.0" +version = "1.16.0" description = "Python 2 and 3 compatibility utilities" category = "main" optional = false @@ -534,25 +551,6 @@ category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -[[package]] -name = "tornado" -version = "6.1" -description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -category = "dev" -optional = false -python-versions = ">= 3.5" - -[[package]] -name = "tqdm" -version = "4.54.1" -description = "Fast, Extensible Progress Meter" -category = "dev" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" - -[package.extras] -dev = ["py-make (>=0.1.0)", "twine", "argopt", "pydoc-markdown", "wheel"] - [[package]] name = "typed-ast" version = "1.4.3" @@ -563,7 +561,7 @@ python-versions = "*" [[package]] name = "typing-extensions" -version = "3.7.4.3" +version = "3.10.0.0" description = "Backported and Experimental Type Hints for Python 3.5+" category = "main" optional = false @@ -580,6 +578,17 @@ python-versions = "*" [package.dependencies] pytz = "*" +[[package]] +name = "watchdog" +version = "2.1.2" +description = "Filesystem events monitoring" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +watchmedo = ["PyYAML (>=3.10)", "argh (>=0.24.1)"] + [[package]] name = "xmltodict" version = "0.12.0" @@ -590,7 +599,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "yq" -version = "2.12.0" +version = "2.12.2" description = "Command-line YAML/XML processor - jq wrapper for YAML/XML documents" category = "dev" optional = false @@ -607,20 +616,20 @@ test = ["coverage", "flake8", "wheel"] [[package]] name = "zipp" -version = "3.4.0" +version = "3.4.1" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false python-versions = ">=3.6" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] [metadata] lock-version = "1.1" python-versions = ">=3.7.0, <3.10" -content-hash = "4d9054a240b279da990b8038623d8b2025487ef37162f7f7ef4a4ff8cbae872b" +content-hash = "4bb72b50e012bd9b58e47835e1fd5d767ce68ac869505f77bb6ad9d564dbf139" [metadata.files] ansiwrap = [ @@ -632,8 +641,8 @@ appdirs = [ {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, ] argcomplete = [ - {file = "argcomplete-1.12.2-py2.py3-none-any.whl", hash = "sha256:17f01a9b9b9ece3e6b07058eae737ad6e10de8b4e149105f84614783913aba71"}, - {file = "argcomplete-1.12.2.tar.gz", hash = "sha256:de0e1282330940d52ea92a80fea2e4b9e0da1932aaa570f84d268939d1897b04"}, + {file = "argcomplete-1.12.3-py2.py3-none-any.whl", hash = "sha256:291f0beca7fd49ce285d2f10e4c1c77e9460cf823eef2de54df0c0fec88b0d81"}, + {file = "argcomplete-1.12.3.tar.gz", hash = "sha256:2c7dbffd8c045ea534921e63b0be6fe65e88599990d8dc408ac8c542b72a5445"}, ] asteval = [ {file = "asteval-0.9.23.tar.gz", hash = "sha256:f5096a924b1d2f147e70327245d95fc8f534dbe94277b6828ce2a8c049d3a438"}, @@ -643,59 +652,59 @@ atomicwrites = [ {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, ] attrs = [ - {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, - {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, + {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, + {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, ] behave = [ {file = "behave-1.2.6-py2.py3-none-any.whl", hash = "sha256:ebda1a6c9e5bfe95c5f9f0a2794e01c7098b3dde86c10a95d8621c5907ff6f1c"}, {file = "behave-1.2.6.tar.gz", hash = "sha256:b9662327aa53294c1351b0a9c369093ccec1d21026f050c3bd9b3e5cccf81a86"}, ] black = [ - {file = "black-21.5b2-py3-none-any.whl", hash = "sha256:e5cf21ebdffc7a9b29d73912b6a6a9a4df4ce70220d523c21647da2eae0751ef"}, - {file = "black-21.5b2.tar.gz", hash = "sha256:1fc0e0a2c8ae7d269dfcf0c60a89afa299664f3e811395d40b1922dff8f854b5"}, + {file = "black-21.6b0-py3-none-any.whl", hash = "sha256:dfb8c5a069012b2ab1e972e7b908f5fb42b6bbabcba0a788b86dc05067c7d9c7"}, + {file = "black-21.6b0.tar.gz", hash = "sha256:dc132348a88d103016726fe360cb9ede02cecf99b76e3660ce6c596be132ce04"}, ] cffi = [ - {file = "cffi-1.14.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ebb253464a5d0482b191274f1c8bf00e33f7e0b9c66405fbffc61ed2c839c775"}, - {file = "cffi-1.14.4-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:2c24d61263f511551f740d1a065eb0212db1dbbbbd241db758f5244281590c06"}, - {file = "cffi-1.14.4-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9f7a31251289b2ab6d4012f6e83e58bc3b96bd151f5b5262467f4bb6b34a7c26"}, - {file = "cffi-1.14.4-cp27-cp27m-win32.whl", hash = "sha256:5cf4be6c304ad0b6602f5c4e90e2f59b47653ac1ed9c662ed379fe48a8f26b0c"}, - {file = "cffi-1.14.4-cp27-cp27m-win_amd64.whl", hash = "sha256:f60567825f791c6f8a592f3c6e3bd93dd2934e3f9dac189308426bd76b00ef3b"}, - {file = "cffi-1.14.4-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:c6332685306b6417a91b1ff9fae889b3ba65c2292d64bd9245c093b1b284809d"}, - {file = "cffi-1.14.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d9efd8b7a3ef378dd61a1e77367f1924375befc2eba06168b6ebfa903a5e59ca"}, - {file = "cffi-1.14.4-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:51a8b381b16ddd370178a65360ebe15fbc1c71cf6f584613a7ea08bfad946698"}, - {file = "cffi-1.14.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1d2c4994f515e5b485fd6d3a73d05526aa0fcf248eb135996b088d25dfa1865b"}, - {file = "cffi-1.14.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:af5c59122a011049aad5dd87424b8e65a80e4a6477419c0c1015f73fb5ea0293"}, - {file = "cffi-1.14.4-cp35-cp35m-win32.whl", hash = "sha256:594234691ac0e9b770aee9fcdb8fa02c22e43e5c619456efd0d6c2bf276f3eb2"}, - {file = "cffi-1.14.4-cp35-cp35m-win_amd64.whl", hash = "sha256:64081b3f8f6f3c3de6191ec89d7dc6c86a8a43911f7ecb422c60e90c70be41c7"}, - {file = "cffi-1.14.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f803eaa94c2fcda012c047e62bc7a51b0bdabda1cad7a92a522694ea2d76e49f"}, - {file = "cffi-1.14.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:105abaf8a6075dc96c1fe5ae7aae073f4696f2905fde6aeada4c9d2926752362"}, - {file = "cffi-1.14.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0638c3ae1a0edfb77c6765d487fee624d2b1ee1bdfeffc1f0b58c64d149e7eec"}, - {file = "cffi-1.14.4-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:7c6b1dece89874d9541fc974917b631406233ea0440d0bdfbb8e03bf39a49b3b"}, - {file = "cffi-1.14.4-cp36-cp36m-win32.whl", hash = "sha256:155136b51fd733fa94e1c2ea5211dcd4c8879869008fc811648f16541bf99668"}, - {file = "cffi-1.14.4-cp36-cp36m-win_amd64.whl", hash = "sha256:6bc25fc545a6b3d57b5f8618e59fc13d3a3a68431e8ca5fd4c13241cd70d0009"}, - {file = "cffi-1.14.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a7711edca4dcef1a75257b50a2fbfe92a65187c47dab5a0f1b9b332c5919a3fb"}, - {file = "cffi-1.14.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:00e28066507bfc3fe865a31f325c8391a1ac2916219340f87dfad602c3e48e5d"}, - {file = "cffi-1.14.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:798caa2a2384b1cbe8a2a139d80734c9db54f9cc155c99d7cc92441a23871c03"}, - {file = "cffi-1.14.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:a5ed8c05548b54b998b9498753fb9cadbfd92ee88e884641377d8a8b291bcc01"}, - {file = "cffi-1.14.4-cp37-cp37m-win32.whl", hash = "sha256:00a1ba5e2e95684448de9b89888ccd02c98d512064b4cb987d48f4b40aa0421e"}, - {file = "cffi-1.14.4-cp37-cp37m-win_amd64.whl", hash = "sha256:9cc46bc107224ff5b6d04369e7c595acb700c3613ad7bcf2e2012f62ece80c35"}, - {file = "cffi-1.14.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:df5169c4396adc04f9b0a05f13c074df878b6052430e03f50e68adf3a57aa28d"}, - {file = "cffi-1.14.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:9ffb888f19d54a4d4dfd4b3f29bc2c16aa4972f1c2ab9c4ab09b8ab8685b9c2b"}, - {file = "cffi-1.14.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8d6603078baf4e11edc4168a514c5ce5b3ba6e3e9c374298cb88437957960a53"}, - {file = "cffi-1.14.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:d5ff0621c88ce83a28a10d2ce719b2ee85635e85c515f12bac99a95306da4b2e"}, - {file = "cffi-1.14.4-cp38-cp38-win32.whl", hash = "sha256:b4e248d1087abf9f4c10f3c398896c87ce82a9856494a7155823eb45a892395d"}, - {file = "cffi-1.14.4-cp38-cp38-win_amd64.whl", hash = "sha256:ec80dc47f54e6e9a78181ce05feb71a0353854cc26999db963695f950b5fb375"}, - {file = "cffi-1.14.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:840793c68105fe031f34d6a086eaea153a0cd5c491cde82a74b420edd0a2b909"}, - {file = "cffi-1.14.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:b18e0a9ef57d2b41f5c68beefa32317d286c3d6ac0484efd10d6e07491bb95dd"}, - {file = "cffi-1.14.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:045d792900a75e8b1e1b0ab6787dd733a8190ffcf80e8c8ceb2fb10a29ff238a"}, - {file = "cffi-1.14.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:7ef7d4ced6b325e92eb4d3502946c78c5367bc416398d387b39591532536734e"}, - {file = "cffi-1.14.4-cp39-cp39-win32.whl", hash = "sha256:ba4e9e0ae13fc41c6b23299545e5ef73055213e466bd107953e4a013a5ddd7e3"}, - {file = "cffi-1.14.4-cp39-cp39-win_amd64.whl", hash = "sha256:f032b34669220030f905152045dfa27741ce1a6db3324a5bc0b96b6c7420c87b"}, - {file = "cffi-1.14.4.tar.gz", hash = "sha256:1a465cbe98a7fd391d47dce4b8f7e5b921e6cd805ef421d04f5f66ba8f06086c"}, + {file = "cffi-1.14.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:bb89f306e5da99f4d922728ddcd6f7fcebb3241fc40edebcb7284d7514741991"}, + {file = "cffi-1.14.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:34eff4b97f3d982fb93e2831e6750127d1355a923ebaeeb565407b3d2f8d41a1"}, + {file = "cffi-1.14.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:99cd03ae7988a93dd00bcd9d0b75e1f6c426063d6f03d2f90b89e29b25b82dfa"}, + {file = "cffi-1.14.5-cp27-cp27m-win32.whl", hash = "sha256:65fa59693c62cf06e45ddbb822165394a288edce9e276647f0046e1ec26920f3"}, + {file = "cffi-1.14.5-cp27-cp27m-win_amd64.whl", hash = "sha256:51182f8927c5af975fece87b1b369f722c570fe169f9880764b1ee3bca8347b5"}, + {file = "cffi-1.14.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:43e0b9d9e2c9e5d152946b9c5fe062c151614b262fda2e7b201204de0b99e482"}, + {file = "cffi-1.14.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:cbde590d4faaa07c72bf979734738f328d239913ba3e043b1e98fe9a39f8b2b6"}, + {file = "cffi-1.14.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:5de7970188bb46b7bf9858eb6890aad302577a5f6f75091fd7cdd3ef13ef3045"}, + {file = "cffi-1.14.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:a465da611f6fa124963b91bf432d960a555563efe4ed1cc403ba5077b15370aa"}, + {file = "cffi-1.14.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:d42b11d692e11b6634f7613ad8df5d6d5f8875f5d48939520d351007b3c13406"}, + {file = "cffi-1.14.5-cp35-cp35m-win32.whl", hash = "sha256:72d8d3ef52c208ee1c7b2e341f7d71c6fd3157138abf1a95166e6165dd5d4369"}, + {file = "cffi-1.14.5-cp35-cp35m-win_amd64.whl", hash = "sha256:29314480e958fd8aab22e4a58b355b629c59bf5f2ac2492b61e3dc06d8c7a315"}, + {file = "cffi-1.14.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3d3dd4c9e559eb172ecf00a2a7517e97d1e96de2a5e610bd9b68cea3925b4892"}, + {file = "cffi-1.14.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:48e1c69bbacfc3d932221851b39d49e81567a4d4aac3b21258d9c24578280058"}, + {file = "cffi-1.14.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:69e395c24fc60aad6bb4fa7e583698ea6cc684648e1ffb7fe85e3c1ca131a7d5"}, + {file = "cffi-1.14.5-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:9e93e79c2551ff263400e1e4be085a1210e12073a31c2011dbbda14bda0c6132"}, + {file = "cffi-1.14.5-cp36-cp36m-win32.whl", hash = "sha256:58e3f59d583d413809d60779492342801d6e82fefb89c86a38e040c16883be53"}, + {file = "cffi-1.14.5-cp36-cp36m-win_amd64.whl", hash = "sha256:005a36f41773e148deac64b08f233873a4d0c18b053d37da83f6af4d9087b813"}, + {file = "cffi-1.14.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2894f2df484ff56d717bead0a5c2abb6b9d2bf26d6960c4604d5c48bbc30ee73"}, + {file = "cffi-1.14.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0857f0ae312d855239a55c81ef453ee8fd24136eaba8e87a2eceba644c0d4c06"}, + {file = "cffi-1.14.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:cd2868886d547469123fadc46eac7ea5253ea7fcb139f12e1dfc2bbd406427d1"}, + {file = "cffi-1.14.5-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:35f27e6eb43380fa080dccf676dece30bef72e4a67617ffda586641cd4508d49"}, + {file = "cffi-1.14.5-cp37-cp37m-win32.whl", hash = "sha256:9ff227395193126d82e60319a673a037d5de84633f11279e336f9c0f189ecc62"}, + {file = "cffi-1.14.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9cf8022fb8d07a97c178b02327b284521c7708d7c71a9c9c355c178ac4bbd3d4"}, + {file = "cffi-1.14.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8b198cec6c72df5289c05b05b8b0969819783f9418e0409865dac47288d2a053"}, + {file = "cffi-1.14.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:ad17025d226ee5beec591b52800c11680fca3df50b8b29fe51d882576e039ee0"}, + {file = "cffi-1.14.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6c97d7350133666fbb5cf4abdc1178c812cb205dc6f41d174a7b0f18fb93337e"}, + {file = "cffi-1.14.5-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8ae6299f6c68de06f136f1f9e69458eae58f1dacf10af5c17353eae03aa0d827"}, + {file = "cffi-1.14.5-cp38-cp38-win32.whl", hash = "sha256:b85eb46a81787c50650f2392b9b4ef23e1f126313b9e0e9013b35c15e4288e2e"}, + {file = "cffi-1.14.5-cp38-cp38-win_amd64.whl", hash = "sha256:1f436816fc868b098b0d63b8920de7d208c90a67212546d02f84fe78a9c26396"}, + {file = "cffi-1.14.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1071534bbbf8cbb31b498d5d9db0f274f2f7a865adca4ae429e147ba40f73dea"}, + {file = "cffi-1.14.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9de2e279153a443c656f2defd67769e6d1e4163952b3c622dcea5b08a6405322"}, + {file = "cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6e4714cc64f474e4d6e37cfff31a814b509a35cb17de4fb1999907575684479c"}, + {file = "cffi-1.14.5-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:158d0d15119b4b7ff6b926536763dc0714313aa59e320ddf787502c70c4d4bee"}, + {file = "cffi-1.14.5-cp39-cp39-win32.whl", hash = "sha256:afb29c1ba2e5a3736f1c301d9d0abe3ec8b86957d04ddfa9d7a6a42b9367e396"}, + {file = "cffi-1.14.5-cp39-cp39-win_amd64.whl", hash = "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d"}, + {file = "cffi-1.14.5.tar.gz", hash = "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"}, ] click = [ - {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, - {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, + {file = "click-8.0.1-py3-none-any.whl", hash = "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"}, + {file = "click-8.0.1.tar.gz", hash = "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a"}, ] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, @@ -715,12 +724,15 @@ cryptography = [ {file = "cryptography-3.4.7-pp37-pypy37_pp73-manylinux2014_x86_64.whl", hash = "sha256:ee77aa129f481be46f8d92a1a7db57269a2f23052d5f2433b4621bb457081cc9"}, {file = "cryptography-3.4.7.tar.gz", hash = "sha256:3d10de8116d25649631977cb37da6cbdd2d6fa0e0281d014a5b7d337255ca713"}, ] -future = [ - {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"}, +ghp-import = [ + {file = "ghp-import-2.0.1.tar.gz", hash = "sha256:753de2eace6e0f7d4edfb3cce5e3c3b98cd52aadb80163303d1d036bda7b4483"}, +] +glob2 = [ + {file = "glob2-0.7.tar.gz", hash = "sha256:85c3dbd07c8aa26d63d7aacee34fa86e9a91a3873bc30bf62ec46e531f92ab8c"}, ] importlib-metadata = [ - {file = "importlib_metadata-3.7.2-py3-none-any.whl", hash = "sha256:407d13f55dc6f2a844e62325d18ad7019a436c4bfcaee34cda35f2be6e7c3e34"}, - {file = "importlib_metadata-3.7.2.tar.gz", hash = "sha256:18d5ff601069f98d5d605b6a4b50c18a34811d655c55548adc833e687289acde"}, + {file = "importlib_metadata-4.5.0-py3-none-any.whl", hash = "sha256:833b26fb89d5de469b24a390e9df088d4e52e4ba33b01dc5e0e4f41b81a16c00"}, + {file = "importlib_metadata-4.5.0.tar.gz", hash = "sha256:b142cc1dd1342f31ff04bb7d022492b09920cb64fed867cd3ea6f80fe3ebd139"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -731,99 +743,74 @@ jeepney = [ {file = "jeepney-0.6.0.tar.gz", hash = "sha256:7d59b6622675ca9e993a6bd38de845051d315f8b0c72cca3aef733a20b648657"}, ] jinja2 = [ - {file = "Jinja2-2.11.2-py2.py3-none-any.whl", hash = "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"}, - {file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"}, -] -joblib = [ - {file = "joblib-0.17.0-py3-none-any.whl", hash = "sha256:698c311779f347cf6b7e6b8a39bb682277b8ee4aba8cf9507bc0cf4cd4737b72"}, - {file = "joblib-0.17.0.tar.gz", hash = "sha256:9e284edd6be6b71883a63c9b7f124738a3c16195513ad940eae7e3438de885d5"}, + {file = "Jinja2-3.0.1-py3-none-any.whl", hash = "sha256:1f06f2da51e7b56b8f238affdd6b4e2c61e39598a378cc49345bc1bd42a978a4"}, + {file = "Jinja2-3.0.1.tar.gz", hash = "sha256:703f484b47a6af502e743c9122595cc812b0271f661722403114f71a79d0f5a4"}, ] keyring = [ {file = "keyring-23.0.1-py3-none-any.whl", hash = "sha256:8f607d7d1cc502c43a932a275a56fe47db50271904513a379d39df1af277ac48"}, {file = "keyring-23.0.1.tar.gz", hash = "sha256:045703609dd3fccfcdb27da201684278823b72af515aedec1a8515719a038cb8"}, ] -livereload = [ - {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, -] -lunr = [ - {file = "lunr-0.5.8-py2.py3-none-any.whl", hash = "sha256:aab3f489c4d4fab4c1294a257a30fec397db56f0a50273218ccc3efdbf01d6ca"}, - {file = "lunr-0.5.8.tar.gz", hash = "sha256:c4fb063b98eff775dd638b3df380008ae85e6cb1d1a24d1cd81a10ef6391c26e"}, +mako = [ + {file = "Mako-1.1.4.tar.gz", hash = "sha256:17831f0b7087c313c0ffae2bcbbd3c1d5ba9eeac9c38f2eb7b50e8c99fe9d5ab"}, ] markdown = [ - {file = "Markdown-3.3.3-py3-none-any.whl", hash = "sha256:c109c15b7dc20a9ac454c9e6025927d44460b85bd039da028d85e2b6d0bcc328"}, - {file = "Markdown-3.3.3.tar.gz", hash = "sha256:5d9f2b5ca24bc4c7a390d22323ca4bad200368612b5aaa7796babf971d2b2f18"}, + {file = "Markdown-3.3.4-py3-none-any.whl", hash = "sha256:96c3ba1261de2f7547b46a00ea8463832c921d3f9d6aba3f255a6f71386db20c"}, + {file = "Markdown-3.3.4.tar.gz", hash = "sha256:31b5b491868dcc87d6c24b7e3d19a0d730d59d3e46f4eea6430a321bed387a49"}, ] markupsafe = [ - {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, - {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"}, - {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"}, - {file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"}, - {file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"}, - {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"}, - {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"}, - {file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"}, - {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"}, - {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, - {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-win32.whl", hash = "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39"}, - {file = "MarkupSafe-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8"}, - {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, + {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, +] +mergedeep = [ + {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, + {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, ] mkdocs = [ - {file = "mkdocs-1.1.2-py3-none-any.whl", hash = "sha256:096f52ff52c02c7e90332d2e53da862fde5c062086e1b5356a6e392d5d60f5e9"}, - {file = "mkdocs-1.1.2.tar.gz", hash = "sha256:f0b61e5402b99d7789efa032c7a74c90a20220a9c81749da06dbfbcbd52ffb39"}, + {file = "mkdocs-1.2.1-py3-none-any.whl", hash = "sha256:11141126e5896dd9d279b3e4814eb488e409a0990fb638856255020406a8e2e7"}, + {file = "mkdocs-1.2.1.tar.gz", hash = "sha256:6e0ea175366e3a50d334597b0bc042b8cebd512398cdd3f6f34842d0ef524905"}, ] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] -nltk = [ - {file = "nltk-3.5.zip", hash = "sha256:845365449cd8c5f9731f7cb9f8bd6fd0767553b9d53af9eb1b3abf7700936b35"}, -] packaging = [ - {file = "packaging-20.8-py2.py3-none-any.whl", hash = "sha256:24e0da08660a87484d1602c30bb4902d74816b6985b93de36926f5bc95741858"}, - {file = "packaging-20.8.tar.gz", hash = "sha256:78598185a7008a470d64526a8059de9aaa449238f280fc9eb6b13ba6c4109093"}, + {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"}, + {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"}, ] parse = [ - {file = "parse-1.18.0.tar.gz", hash = "sha256:91666032d6723dc5905248417ef0dc9e4c51df9526aaeef271eacad6491f06a4"}, + {file = "parse-1.19.0.tar.gz", hash = "sha256:9ff82852bcb65d139813e2a5197627a94966245c897796760a3a2a8eb66f020b"}, ] parse-type = [ {file = "parse_type-0.5.2-py2.py3-none-any.whl", hash = "sha256:089a471b06327103865dfec2dd844230c3c658a4a1b5b4c8b6c16c8f77577f9e"}, @@ -861,6 +848,10 @@ pytest = [ {file = "pytest-6.2.4-py3-none-any.whl", hash = "sha256:91ef2131a9bd6be8f76f1f08eac5c5317221d6ad1e143ae03894b862e8976890"}, {file = "pytest-6.2.4.tar.gz", hash = "sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b"}, ] +pytest-bdd = [ + {file = "pytest-bdd-4.0.2.tar.gz", hash = "sha256:982489f2f036c7561affe4eeb5b392a37e1ace2a9f260cad747b1c8119e63cfd"}, + {file = "pytest_bdd-4.0.2-py2.py3-none-any.whl", hash = "sha256:74ea5a147ea558c99ae83d838e6acbe5c9e6843884a958f8231615d96838733d"}, +] python-dateutil = [ {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, @@ -884,80 +875,76 @@ pyyaml = [ {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, ] +pyyaml-env-tag = [ + {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, + {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, +] regex = [ - {file = "regex-2020.11.13-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8b882a78c320478b12ff024e81dc7d43c1462aa4a3341c754ee65d857a521f85"}, - {file = "regex-2020.11.13-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a63f1a07932c9686d2d416fb295ec2c01ab246e89b4d58e5fa468089cab44b70"}, - {file = "regex-2020.11.13-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:6e4b08c6f8daca7d8f07c8d24e4331ae7953333dbd09c648ed6ebd24db5a10ee"}, - {file = "regex-2020.11.13-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:bba349276b126947b014e50ab3316c027cac1495992f10e5682dc677b3dfa0c5"}, - {file = "regex-2020.11.13-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:56e01daca75eae420bce184edd8bb341c8eebb19dd3bce7266332258f9fb9dd7"}, - {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:6a8ce43923c518c24a2579fda49f093f1397dad5d18346211e46f134fc624e31"}, - {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:1ab79fcb02b930de09c76d024d279686ec5d532eb814fd0ed1e0051eb8bd2daa"}, - {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:9801c4c1d9ae6a70aeb2128e5b4b68c45d4f0af0d1535500884d644fa9b768c6"}, - {file = "regex-2020.11.13-cp36-cp36m-win32.whl", hash = "sha256:49cae022fa13f09be91b2c880e58e14b6da5d10639ed45ca69b85faf039f7a4e"}, - {file = "regex-2020.11.13-cp36-cp36m-win_amd64.whl", hash = "sha256:749078d1eb89484db5f34b4012092ad14b327944ee7f1c4f74d6279a6e4d1884"}, - {file = "regex-2020.11.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b2f4007bff007c96a173e24dcda236e5e83bde4358a557f9ccf5e014439eae4b"}, - {file = "regex-2020.11.13-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:38c8fd190db64f513fe4e1baa59fed086ae71fa45083b6936b52d34df8f86a88"}, - {file = "regex-2020.11.13-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5862975b45d451b6db51c2e654990c1820523a5b07100fc6903e9c86575202a0"}, - {file = "regex-2020.11.13-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:262c6825b309e6485ec2493ffc7e62a13cf13fb2a8b6d212f72bd53ad34118f1"}, - {file = "regex-2020.11.13-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:bafb01b4688833e099d79e7efd23f99172f501a15c44f21ea2118681473fdba0"}, - {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:e32f5f3d1b1c663af7f9c4c1e72e6ffe9a78c03a31e149259f531e0fed826512"}, - {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:3bddc701bdd1efa0d5264d2649588cbfda549b2899dc8d50417e47a82e1387ba"}, - {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:02951b7dacb123d8ea6da44fe45ddd084aa6777d4b2454fa0da61d569c6fa538"}, - {file = "regex-2020.11.13-cp37-cp37m-win32.whl", hash = "sha256:0d08e71e70c0237883d0bef12cad5145b84c3705e9c6a588b2a9c7080e5af2a4"}, - {file = "regex-2020.11.13-cp37-cp37m-win_amd64.whl", hash = "sha256:1fa7ee9c2a0e30405e21031d07d7ba8617bc590d391adfc2b7f1e8b99f46f444"}, - {file = "regex-2020.11.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:baf378ba6151f6e272824b86a774326f692bc2ef4cc5ce8d5bc76e38c813a55f"}, - {file = "regex-2020.11.13-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e3faaf10a0d1e8e23a9b51d1900b72e1635c2d5b0e1bea1c18022486a8e2e52d"}, - {file = "regex-2020.11.13-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2a11a3e90bd9901d70a5b31d7dd85114755a581a5da3fc996abfefa48aee78af"}, - {file = "regex-2020.11.13-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1ebb090a426db66dd80df8ca85adc4abfcbad8a7c2e9a5ec7513ede522e0a8f"}, - {file = "regex-2020.11.13-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:b2b1a5ddae3677d89b686e5c625fc5547c6e492bd755b520de5332773a8af06b"}, - {file = "regex-2020.11.13-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:2c99e97d388cd0a8d30f7c514d67887d8021541b875baf09791a3baad48bb4f8"}, - {file = "regex-2020.11.13-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:c084582d4215593f2f1d28b65d2a2f3aceff8342aa85afd7be23a9cad74a0de5"}, - {file = "regex-2020.11.13-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:a3d748383762e56337c39ab35c6ed4deb88df5326f97a38946ddd19028ecce6b"}, - {file = "regex-2020.11.13-cp38-cp38-win32.whl", hash = "sha256:7913bd25f4ab274ba37bc97ad0e21c31004224ccb02765ad984eef43e04acc6c"}, - {file = "regex-2020.11.13-cp38-cp38-win_amd64.whl", hash = "sha256:6c54ce4b5d61a7129bad5c5dc279e222afd00e721bf92f9ef09e4fae28755683"}, - {file = "regex-2020.11.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1862a9d9194fae76a7aaf0150d5f2a8ec1da89e8b55890b1786b8f88a0f619dc"}, - {file = "regex-2020.11.13-cp39-cp39-manylinux1_i686.whl", hash = "sha256:4902e6aa086cbb224241adbc2f06235927d5cdacffb2425c73e6570e8d862364"}, - {file = "regex-2020.11.13-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7a25fcbeae08f96a754b45bdc050e1fb94b95cab046bf56b016c25e9ab127b3e"}, - {file = "regex-2020.11.13-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:d2d8ce12b7c12c87e41123997ebaf1a5767a5be3ec545f64675388970f415e2e"}, - {file = "regex-2020.11.13-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:f7d29a6fc4760300f86ae329e3b6ca28ea9c20823df123a2ea8693e967b29917"}, - {file = "regex-2020.11.13-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:717881211f46de3ab130b58ec0908267961fadc06e44f974466d1887f865bd5b"}, - {file = "regex-2020.11.13-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:3128e30d83f2e70b0bed9b2a34e92707d0877e460b402faca908c6667092ada9"}, - {file = "regex-2020.11.13-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:8f6a2229e8ad946e36815f2a03386bb8353d4bde368fdf8ca5f0cb97264d3b5c"}, - {file = "regex-2020.11.13-cp39-cp39-win32.whl", hash = "sha256:f8f295db00ef5f8bae530fc39af0b40486ca6068733fb860b42115052206466f"}, - {file = "regex-2020.11.13-cp39-cp39-win_amd64.whl", hash = "sha256:a15f64ae3a027b64496a71ab1f722355e570c3fac5ba2801cafce846bf5af01d"}, - {file = "regex-2020.11.13.tar.gz", hash = "sha256:83d6b356e116ca119db8e7c6fc2983289d87b27b3fac238cfe5dca529d884562"}, + {file = "regex-2021.4.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:619d71c59a78b84d7f18891fe914446d07edd48dc8328c8e149cbe0929b4e000"}, + {file = "regex-2021.4.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:47bf5bf60cf04d72bf6055ae5927a0bd9016096bf3d742fa50d9bf9f45aa0711"}, + {file = "regex-2021.4.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:281d2fd05555079448537fe108d79eb031b403dac622621c78944c235f3fcf11"}, + {file = "regex-2021.4.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:bd28bc2e3a772acbb07787c6308e00d9626ff89e3bfcdebe87fa5afbfdedf968"}, + {file = "regex-2021.4.4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:7c2a1af393fcc09e898beba5dd59196edaa3116191cc7257f9224beaed3e1aa0"}, + {file = "regex-2021.4.4-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c38c71df845e2aabb7fb0b920d11a1b5ac8526005e533a8920aea97efb8ec6a4"}, + {file = "regex-2021.4.4-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:96fcd1888ab4d03adfc9303a7b3c0bd78c5412b2bfbe76db5b56d9eae004907a"}, + {file = "regex-2021.4.4-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:ade17eb5d643b7fead300a1641e9f45401c98eee23763e9ed66a43f92f20b4a7"}, + {file = "regex-2021.4.4-cp36-cp36m-win32.whl", hash = "sha256:e8e5b509d5c2ff12f8418006d5a90e9436766133b564db0abaec92fd27fcee29"}, + {file = "regex-2021.4.4-cp36-cp36m-win_amd64.whl", hash = "sha256:11d773d75fa650cd36f68d7ca936e3c7afaae41b863b8c387a22aaa78d3c5c79"}, + {file = "regex-2021.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d3029c340cfbb3ac0a71798100ccc13b97dddf373a4ae56b6a72cf70dfd53bc8"}, + {file = "regex-2021.4.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:18c071c3eb09c30a264879f0d310d37fe5d3a3111662438889ae2eb6fc570c31"}, + {file = "regex-2021.4.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:4c557a7b470908b1712fe27fb1ef20772b78079808c87d20a90d051660b1d69a"}, + {file = "regex-2021.4.4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:01afaf2ec48e196ba91b37451aa353cb7eda77efe518e481707e0515025f0cd5"}, + {file = "regex-2021.4.4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:3a9cd17e6e5c7eb328517969e0cb0c3d31fd329298dd0c04af99ebf42e904f82"}, + {file = "regex-2021.4.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:90f11ff637fe8798933fb29f5ae1148c978cccb0452005bf4c69e13db951e765"}, + {file = "regex-2021.4.4-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:919859aa909429fb5aa9cf8807f6045592c85ef56fdd30a9a3747e513db2536e"}, + {file = "regex-2021.4.4-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:339456e7d8c06dd36a22e451d58ef72cef293112b559010db3d054d5560ef439"}, + {file = "regex-2021.4.4-cp37-cp37m-win32.whl", hash = "sha256:67bdb9702427ceddc6ef3dc382455e90f785af4c13d495f9626861763ee13f9d"}, + {file = "regex-2021.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:32e65442138b7b76dd8173ffa2cf67356b7bc1768851dded39a7a13bf9223da3"}, + {file = "regex-2021.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1e1c20e29358165242928c2de1482fb2cf4ea54a6a6dea2bd7a0e0d8ee321500"}, + {file = "regex-2021.4.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:314d66636c494ed9c148a42731b3834496cc9a2c4251b1661e40936814542b14"}, + {file = "regex-2021.4.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6d1b01031dedf2503631d0903cb563743f397ccaf6607a5e3b19a3d76fc10480"}, + {file = "regex-2021.4.4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:741a9647fcf2e45f3a1cf0e24f5e17febf3efe8d4ba1281dcc3aa0459ef424dc"}, + {file = "regex-2021.4.4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4c46e22a0933dd783467cf32b3516299fb98cfebd895817d685130cc50cd1093"}, + {file = "regex-2021.4.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:e512d8ef5ad7b898cdb2d8ee1cb09a8339e4f8be706d27eaa180c2f177248a10"}, + {file = "regex-2021.4.4-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:980d7be47c84979d9136328d882f67ec5e50008681d94ecc8afa8a65ed1f4a6f"}, + {file = "regex-2021.4.4-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:ce15b6d103daff8e9fee13cf7f0add05245a05d866e73926c358e871221eae87"}, + {file = "regex-2021.4.4-cp38-cp38-win32.whl", hash = "sha256:a91aa8619b23b79bcbeb37abe286f2f408d2f2d6f29a17237afda55bb54e7aac"}, + {file = "regex-2021.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:c0502c0fadef0d23b128605d69b58edb2c681c25d44574fc673b0e52dce71ee2"}, + {file = "regex-2021.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:598585c9f0af8374c28edd609eb291b5726d7cbce16be6a8b95aa074d252ee17"}, + {file = "regex-2021.4.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:ee54ff27bf0afaf4c3b3a62bcd016c12c3fdb4ec4f413391a90bd38bc3624605"}, + {file = "regex-2021.4.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7d9884d86dd4dd489e981d94a65cd30d6f07203d90e98f6f657f05170f6324c9"}, + {file = "regex-2021.4.4-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:bf5824bfac591ddb2c1f0a5f4ab72da28994548c708d2191e3b87dd207eb3ad7"}, + {file = "regex-2021.4.4-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:563085e55b0d4fb8f746f6a335893bda5c2cef43b2f0258fe1020ab1dd874df8"}, + {file = "regex-2021.4.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9c3db21af35e3b3c05764461b262d6f05bbca08a71a7849fd79d47ba7bc33ed"}, + {file = "regex-2021.4.4-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:3916d08be28a1149fb97f7728fca1f7c15d309a9f9682d89d79db75d5e52091c"}, + {file = "regex-2021.4.4-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:fd45ff9293d9274c5008a2054ecef86a9bfe819a67c7be1afb65e69b405b3042"}, + {file = "regex-2021.4.4-cp39-cp39-win32.whl", hash = "sha256:fa4537fb4a98fe8fde99626e4681cc644bdcf2a795038533f9f711513a862ae6"}, + {file = "regex-2021.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:97f29f57d5b84e73fbaf99ab3e26134e6687348e95ef6b48cfd2c06807005a07"}, + {file = "regex-2021.4.4.tar.gz", hash = "sha256:52ba3d3f9b942c49d7e4bc105bb28551c44065f139a65062ab7912bef10c9afb"}, ] secretstorage = [ - {file = "SecretStorage-3.3.0-py3-none-any.whl", hash = "sha256:5c36f6537a523ec5f969ef9fad61c98eb9e017bc601d811e53aa25bece64892f"}, - {file = "SecretStorage-3.3.0.tar.gz", hash = "sha256:30cfdef28829dad64d6ea1ed08f8eff6aa115a77068926bcc9f5225d5a3246aa"}, + {file = "SecretStorage-3.3.1-py3-none-any.whl", hash = "sha256:422d82c36172d88d6a0ed5afdec956514b189ddbfb72fefab0c8a1cee4eaf71f"}, + {file = "SecretStorage-3.3.1.tar.gz", hash = "sha256:fd666c51a6bf200643495a04abb261f83229dcb6fd8472ec393df7ffc8b6f195"}, ] six = [ - {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, - {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] textwrap3 = [ {file = "textwrap3-0.9.2-py2.py3-none-any.whl", hash = "sha256:bf5f4c40faf2a9ff00a9e0791fed5da7415481054cef45bb4a3cfb1f69044ae0"}, @@ -967,53 +954,6 @@ toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] -tornado = [ - {file = "tornado-6.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32"}, - {file = "tornado-6.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c"}, - {file = "tornado-6.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9de9e5188a782be6b1ce866e8a51bc76a0fbaa0e16613823fc38e4fc2556ad05"}, - {file = "tornado-6.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:61b32d06ae8a036a6607805e6720ef00a3c98207038444ba7fd3d169cd998910"}, - {file = "tornado-6.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:3e63498f680547ed24d2c71e6497f24bca791aca2fe116dbc2bd0ac7f191691b"}, - {file = "tornado-6.1-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:6c77c9937962577a6a76917845d06af6ab9197702a42e1346d8ae2e76b5e3675"}, - {file = "tornado-6.1-cp35-cp35m-win32.whl", hash = "sha256:6286efab1ed6e74b7028327365cf7346b1d777d63ab30e21a0f4d5b275fc17d5"}, - {file = "tornado-6.1-cp35-cp35m-win_amd64.whl", hash = "sha256:fa2ba70284fa42c2a5ecb35e322e68823288a4251f9ba9cc77be04ae15eada68"}, - {file = "tornado-6.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0a00ff4561e2929a2c37ce706cb8233b7907e0cdc22eab98888aca5dd3775feb"}, - {file = "tornado-6.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:748290bf9112b581c525e6e6d3820621ff020ed95af6f17fedef416b27ed564c"}, - {file = "tornado-6.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:e385b637ac3acaae8022e7e47dfa7b83d3620e432e3ecb9a3f7f58f150e50921"}, - {file = "tornado-6.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:25ad220258349a12ae87ede08a7b04aca51237721f63b1808d39bdb4b2164558"}, - {file = "tornado-6.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:65d98939f1a2e74b58839f8c4dab3b6b3c1ce84972ae712be02845e65391ac7c"}, - {file = "tornado-6.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:e519d64089b0876c7b467274468709dadf11e41d65f63bba207e04217f47c085"}, - {file = "tornado-6.1-cp36-cp36m-win32.whl", hash = "sha256:b87936fd2c317b6ee08a5741ea06b9d11a6074ef4cc42e031bc6403f82a32575"}, - {file = "tornado-6.1-cp36-cp36m-win_amd64.whl", hash = "sha256:cc0ee35043162abbf717b7df924597ade8e5395e7b66d18270116f8745ceb795"}, - {file = "tornado-6.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7250a3fa399f08ec9cb3f7b1b987955d17e044f1ade821b32e5f435130250d7f"}, - {file = "tornado-6.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ed3ad863b1b40cd1d4bd21e7498329ccaece75db5a5bf58cd3c9f130843e7102"}, - {file = "tornado-6.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:dcef026f608f678c118779cd6591c8af6e9b4155c44e0d1bc0c87c036fb8c8c4"}, - {file = "tornado-6.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:70dec29e8ac485dbf57481baee40781c63e381bebea080991893cd297742b8fd"}, - {file = "tornado-6.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:d3f7594930c423fd9f5d1a76bee85a2c36fd8b4b16921cae7e965f22575e9c01"}, - {file = "tornado-6.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3447475585bae2e77ecb832fc0300c3695516a47d46cefa0528181a34c5b9d3d"}, - {file = "tornado-6.1-cp37-cp37m-win32.whl", hash = "sha256:e7229e60ac41a1202444497ddde70a48d33909e484f96eb0da9baf8dc68541df"}, - {file = "tornado-6.1-cp37-cp37m-win_amd64.whl", hash = "sha256:cb5ec8eead331e3bb4ce8066cf06d2dfef1bfb1b2a73082dfe8a161301b76e37"}, - {file = "tornado-6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:20241b3cb4f425e971cb0a8e4ffc9b0a861530ae3c52f2b0434e6c1b57e9fd95"}, - {file = "tornado-6.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c77da1263aa361938476f04c4b6c8916001b90b2c2fdd92d8d535e1af48fba5a"}, - {file = "tornado-6.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:fba85b6cd9c39be262fcd23865652920832b61583de2a2ca907dbd8e8a8c81e5"}, - {file = "tornado-6.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:1e8225a1070cd8eec59a996c43229fe8f95689cb16e552d130b9793cb570a288"}, - {file = "tornado-6.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d14d30e7f46a0476efb0deb5b61343b1526f73ebb5ed84f23dc794bdb88f9d9f"}, - {file = "tornado-6.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8f959b26f2634a091bb42241c3ed8d3cedb506e7c27b8dd5c7b9f745318ddbb6"}, - {file = "tornado-6.1-cp38-cp38-win32.whl", hash = "sha256:34ca2dac9e4d7afb0bed4677512e36a52f09caa6fded70b4e3e1c89dbd92c326"}, - {file = "tornado-6.1-cp38-cp38-win_amd64.whl", hash = "sha256:6196a5c39286cc37c024cd78834fb9345e464525d8991c21e908cc046d1cc02c"}, - {file = "tornado-6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0ba29bafd8e7e22920567ce0d232c26d4d47c8b5cf4ed7b562b5db39fa199c5"}, - {file = "tornado-6.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:33892118b165401f291070100d6d09359ca74addda679b60390b09f8ef325ffe"}, - {file = "tornado-6.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7da13da6f985aab7f6f28debab00c67ff9cbacd588e8477034c0652ac141feea"}, - {file = "tornado-6.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:e0791ac58d91ac58f694d8d2957884df8e4e2f6687cdf367ef7eb7497f79eaa2"}, - {file = "tornado-6.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:66324e4e1beede9ac79e60f88de548da58b1f8ab4b2f1354d8375774f997e6c0"}, - {file = "tornado-6.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:a48900ecea1cbb71b8c71c620dee15b62f85f7c14189bdeee54966fbd9a0c5bd"}, - {file = "tornado-6.1-cp39-cp39-win32.whl", hash = "sha256:d3d20ea5782ba63ed13bc2b8c291a053c8d807a8fa927d941bd718468f7b950c"}, - {file = "tornado-6.1-cp39-cp39-win_amd64.whl", hash = "sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4"}, - {file = "tornado-6.1.tar.gz", hash = "sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791"}, -] -tqdm = [ - {file = "tqdm-4.54.1-py2.py3-none-any.whl", hash = "sha256:d4f413aecb61c9779888c64ddf0c62910ad56dcbe857d8922bb505d4dbff0df1"}, - {file = "tqdm-4.54.1.tar.gz", hash = "sha256:38b658a3e4ecf9b4f6f8ff75ca16221ae3378b2e175d846b6b33ea3a20852cf5"}, -] typed-ast = [ {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"}, {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"}, @@ -1047,23 +987,42 @@ typed-ast = [ {file = "typed_ast-1.4.3.tar.gz", hash = "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65"}, ] typing-extensions = [ - {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"}, - {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"}, - {file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"}, + {file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"}, + {file = "typing_extensions-3.10.0.0-py3-none-any.whl", hash = "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"}, + {file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"}, ] tzlocal = [ {file = "tzlocal-2.1-py2.py3-none-any.whl", hash = "sha256:e2cb6c6b5b604af38597403e9852872d7f534962ae2954c7f35efcb1ccacf4a4"}, {file = "tzlocal-2.1.tar.gz", hash = "sha256:643c97c5294aedc737780a49d9df30889321cbe1204eac2c2ec6134035a92e44"}, ] +watchdog = [ + {file = "watchdog-2.1.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:581e3548159fe7d2a9f377a1fbcb41bdcee46849cca8ab803c7ac2e5e04ec77c"}, + {file = "watchdog-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:edcd9ef3fd460bb8a98eb1fcf99941e9fd9f275f45f1a82cb1359ec92975d647"}, + {file = "watchdog-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d34ce2261f118ecd57eedeef95fc2a495fc4a40b3ed7b3bf0bd7a8ccc1ab4f8f"}, + {file = "watchdog-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:668391e6c32742d76e5be5db6bf95c455fa4b3d11e76a77c13b39bccb3a47a72"}, + {file = "watchdog-2.1.2-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6ef9fe57162c4c361692620e1d9167574ba1975ee468b24051ca11c9bba6438e"}, + {file = "watchdog-2.1.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:58ebb1095ee493008a7789d47dd62e4999505d82be89fc884d473086fccc6ebd"}, + {file = "watchdog-2.1.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:91387ee2421f30b75f7ff632c9d48f76648e56bf346a7c805c0a34187a93aab4"}, + {file = "watchdog-2.1.2-py3-none-manylinux2014_armv7l.whl", hash = "sha256:a6471517315a8541a943c00b45f1d252e36898a3ae963d2d52509b89a50cb2b9"}, + {file = "watchdog-2.1.2-py3-none-manylinux2014_i686.whl", hash = "sha256:a42e6d652f820b2b94cd03156c62559a2ea68d476476dfcd77d931e7f1012d4a"}, + {file = "watchdog-2.1.2-py3-none-manylinux2014_ppc64.whl", hash = "sha256:3d6405681471ebe0beb3aa083998c4870e48b57f8afdb45ea1b5957cc5cf1014"}, + {file = "watchdog-2.1.2-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:598d772beeaf9c98d0df946fbabf0c8365dd95ea46a250c224c725fe0c4730bc"}, + {file = "watchdog-2.1.2-py3-none-manylinux2014_s390x.whl", hash = "sha256:4b219d46d89cfa49af1d73175487c14a318a74cb8c5442603fd13c6a5b418c86"}, + {file = "watchdog-2.1.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:188145185c08c73c56f1478ccf1f0f0f85101191439679b35b6b100886ce0b39"}, + {file = "watchdog-2.1.2-py3-none-win32.whl", hash = "sha256:255a32d44bbbe62e52874ff755e2eefe271b150e0ec240ad7718a62a7a7a73c4"}, + {file = "watchdog-2.1.2-py3-none-win_amd64.whl", hash = "sha256:1a62a4671796dc93d1a7262286217d9e75823c63d4c42782912d39a506d30046"}, + {file = "watchdog-2.1.2-py3-none-win_ia64.whl", hash = "sha256:104266a778906ae0e971368d368a65c4cd032a490a9fca5ba0b78c6c7ae11720"}, + {file = "watchdog-2.1.2.tar.gz", hash = "sha256:0237db4d9024859bea27d0efb59fe75eef290833fd988b8ead7a879b0308c2db"}, +] xmltodict = [ {file = "xmltodict-0.12.0-py2.py3-none-any.whl", hash = "sha256:8bbcb45cc982f48b2ca8fe7e7827c5d792f217ecf1792626f808bf41c3b86051"}, {file = "xmltodict-0.12.0.tar.gz", hash = "sha256:50d8c638ed7ecb88d90561beedbf720c9b4e851a9fa6c47ebd64e99d166d8a21"}, ] yq = [ - {file = "yq-2.12.0-py2.py3-none-any.whl", hash = "sha256:1f124f48dee77ad5e0be8607777fed183e96c8d31fa577de14201c7a614e4819"}, - {file = "yq-2.12.0.tar.gz", hash = "sha256:1d2ad403504d306b5258b86c698f9856d7ad58b7bb17a2b875691a6a7b8c4c20"}, + {file = "yq-2.12.2-py2.py3-none-any.whl", hash = "sha256:9fdf4487a6dbf985ca1d357ec93f926d982813e8e896e8892bae95162b6defe3"}, + {file = "yq-2.12.2.tar.gz", hash = "sha256:2f156d0724b61487ac8752ed4eaa702a5737b804d5afa46fa55866951cd106d2"}, ] zipp = [ - {file = "zipp-3.4.0-py3-none-any.whl", hash = "sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108"}, - {file = "zipp-3.4.0.tar.gz", hash = "sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb"}, + {file = "zipp-3.4.1-py3-none-any.whl", hash = "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098"}, + {file = "zipp-3.4.1.tar.gz", hash = "sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76"}, ] diff --git a/pyproject.toml b/pyproject.toml index 8a46fe34..b8c4731e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,6 +50,7 @@ black = {version = "^21.5b2",allow-prereleases = true} toml = ">=0.10" pyflakes = ">=2.2.0" pytest = ">=6.2" +pytest-bdd = "^4.0.1" yq = ">=2.11" [tool.poetry.scripts] @@ -62,6 +63,9 @@ line_length = 88 known_first_party = ["jrnl"] force_sort_within_sections = true +[tool.pytest.ini_options] +minversion = "6.0" + [build-system] requires = ["poetry>=1.1"] build-backend = "poetry.masonry.api" diff --git a/tests/features/build.feature b/tests/features/build.feature new file mode 100644 index 00000000..4725ea85 --- /dev/null +++ b/tests/features/build.feature @@ -0,0 +1,8 @@ +Feature: Build process + + @deployment_tests + Scenario: Version numbers should stay in sync + Given we use the config "simple.yaml" + When we run "jrnl --version" + Then we should get no error + And the output should contain pyproject.toml version diff --git a/tests/features/configs/basic_dayone.yaml b/tests/features/configs/basic_dayone.yaml new file mode 100644 index 00000000..0209f2f7 --- /dev/null +++ b/tests/features/configs/basic_dayone.yaml @@ -0,0 +1,17 @@ +colors: + date: none + title: none + body: none + tags: none +default_hour: 9 +default_minute: 0 +editor: noop +encrypt: false +highlight: true +journals: + default: features/journals/basic_dayone.dayone +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/configs/basic_encrypted.yaml b/tests/features/configs/basic_encrypted.yaml new file mode 100644 index 00000000..77f4e48d --- /dev/null +++ b/tests/features/configs/basic_encrypted.yaml @@ -0,0 +1,17 @@ +colors: + date: none + title: none + body: none + tags: none +default_hour: 9 +default_minute: 0 +editor: noop +encrypt: true +highlight: true +journals: + default: features/journals/basic_encrypted.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/configs/basic_folder.yaml b/tests/features/configs/basic_folder.yaml new file mode 100644 index 00000000..ba0de638 --- /dev/null +++ b/tests/features/configs/basic_folder.yaml @@ -0,0 +1,17 @@ +colors: + date: none + title: none + body: none + tags: none +default_hour: 9 +default_minute: 0 +editor: noop +encrypt: false +highlight: true +journals: + default: features/journals/basic_folder +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/configs/basic_onefile.yaml b/tests/features/configs/basic_onefile.yaml new file mode 100644 index 00000000..fb48c6f8 --- /dev/null +++ b/tests/features/configs/basic_onefile.yaml @@ -0,0 +1,17 @@ +colors: + date: none + title: none + body: none + tags: none +default_hour: 9 +default_minute: 0 +editor: noop +encrypt: false +highlight: true +journals: + default: features/journals/basic_onefile.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/configs/brackets.yaml b/tests/features/configs/brackets.yaml new file mode 100644 index 00000000..e658947c --- /dev/null +++ b/tests/features/configs/brackets.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/brackets.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/configs/bug153.yaml b/tests/features/configs/bug153.yaml new file mode 100644 index 00000000..ff645ab6 --- /dev/null +++ b/tests/features/configs/bug153.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: false +highlight: true +journals: + default: features/journals/bug153.dayone +linewrap: 80 +tagsymbols: '@' +template: false +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/configs/bug343.yaml b/tests/features/configs/bug343.yaml new file mode 100644 index 00000000..a4e25d8a --- /dev/null +++ b/tests/features/configs/bug343.yaml @@ -0,0 +1,13 @@ +default_hour: 9 +default_minute: 0 +editor: '' +template: false +encrypt: false +highlight: true +journals: + simple: features/journals/simple.journal + work: features/journals/work.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/configs/bug780.yaml b/tests/features/configs/bug780.yaml new file mode 100644 index 00000000..e1d830c2 --- /dev/null +++ b/tests/features/configs/bug780.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: false +highlight: true +journals: + default: features/journals/bug780.dayone +linewrap: 80 +tagsymbols: '@' +template: false +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/configs/dayone.yaml b/tests/features/configs/dayone.yaml new file mode 100644 index 00000000..894cb911 --- /dev/null +++ b/tests/features/configs/dayone.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: noop +template: false +encrypt: false +highlight: true +journals: + default: features/journals/dayone.dayone +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/configs/dayone_empty.yaml b/tests/features/configs/dayone_empty.yaml new file mode 100644 index 00000000..7750d389 --- /dev/null +++ b/tests/features/configs/dayone_empty.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: noop +template: false +encrypt: false +highlight: true +journals: + default: features/journals/dayone_empty.dayone +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/configs/deletion.yaml b/tests/features/configs/deletion.yaml new file mode 100644 index 00000000..d4155260 --- /dev/null +++ b/tests/features/configs/deletion.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/deletion.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/configs/deletion_filters.yaml b/tests/features/configs/deletion_filters.yaml new file mode 100644 index 00000000..73a88e4d --- /dev/null +++ b/tests/features/configs/deletion_filters.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/deletion_filters.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/configs/editor-args.yaml b/tests/features/configs/editor-args.yaml new file mode 100644 index 00000000..12c5bd9c --- /dev/null +++ b/tests/features/configs/editor-args.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: vim -f -c 'setf markdown' +encrypt: false +highlight: true +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/configs/editor.yaml b/tests/features/configs/editor.yaml new file mode 100644 index 00000000..8a06f916 --- /dev/null +++ b/tests/features/configs/editor.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "vim" +encrypt: false +highlight: true +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/configs/editor_empty_folder.yaml b/tests/features/configs/editor_empty_folder.yaml new file mode 100644 index 00000000..1724bbfb --- /dev/null +++ b/tests/features/configs/editor_empty_folder.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: 'vim' +template: false +encrypt: false +highlight: true +journals: + default: features/journals/empty_folder +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/configs/editor_encrypted.yaml b/tests/features/configs/editor_encrypted.yaml new file mode 100644 index 00000000..75273c96 --- /dev/null +++ b/tests/features/configs/editor_encrypted.yaml @@ -0,0 +1,17 @@ +colors: + body: green + date: blue + tags: none + title: yellow +default_hour: 9 +default_minute: 0 +editor: "vim" +encrypt: true +template: false +highlight: true +journals: + default: features/journals/encrypted.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/configs/editor_markdown_extension.yaml b/tests/features/configs/editor_markdown_extension.yaml new file mode 100644 index 00000000..bf3b8d8e --- /dev/null +++ b/tests/features/configs/editor_markdown_extension.yaml @@ -0,0 +1,18 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +editor: "vim" +journals: + default: features/journals/editor_markdown_extension.journal +linewrap: 80 +tagsymbols: "@" +template: features/templates/extension.md +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/configs/empty_folder.yaml b/tests/features/configs/empty_folder.yaml new file mode 100644 index 00000000..52a21854 --- /dev/null +++ b/tests/features/configs/empty_folder.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: '' +template: false +encrypt: false +highlight: true +journals: + default: features/journals/empty_folder +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/configs/encrypted.yaml b/tests/features/configs/encrypted.yaml new file mode 100644 index 00000000..4d50b607 --- /dev/null +++ b/tests/features/configs/encrypted.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: true +template: false +highlight: true +journals: + default: features/journals/encrypted.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/configs/encrypted_old.json b/tests/features/configs/encrypted_old.json new file mode 100644 index 00000000..e69d9b79 --- /dev/null +++ b/tests/features/configs/encrypted_old.json @@ -0,0 +1,13 @@ +{ + "default_hour": 9, + "default_minute": 0, + "editor": "", + "encrypt": true, + "highlight": true, + "journals": { + "default": "features/journals/encrypted_jrnl-1-9-5.journal" + }, + "linewrap": 80, + "tagsymbols": "@", + "timeformat": "%Y-%m-%d %H:%M" +} diff --git a/tests/features/configs/encrypted_old.yaml b/tests/features/configs/encrypted_old.yaml new file mode 100644 index 00000000..bc7b1440 --- /dev/null +++ b/tests/features/configs/encrypted_old.yaml @@ -0,0 +1,11 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: true +highlight: true +journals: + default: features/journals/encrypted_jrnl1-9-5.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/configs/format_md.yaml b/tests/features/configs/format_md.yaml new file mode 100644 index 00000000..0b9f1c3b --- /dev/null +++ b/tests/features/configs/format_md.yaml @@ -0,0 +1,19 @@ +colors: + body: none + date: none + tags: none + title: none +default_hour: 9 +default_minute: 0 +display_format: markdown +editor: '' +encrypt: false +highlight: true +indent_character: '|' +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: '@' +template: false +timeformat: '%Y-%m-%d %H:%M' +version: v2.4.5 diff --git a/tests/features/configs/format_text.yaml b/tests/features/configs/format_text.yaml new file mode 100644 index 00000000..c82ff7a7 --- /dev/null +++ b/tests/features/configs/format_text.yaml @@ -0,0 +1,19 @@ +colors: + body: none + date: none + tags: none + title: none +default_hour: 9 +default_minute: 0 +display_format: text +editor: '' +encrypt: false +highlight: true +indent_character: '|' +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: '@' +template: false +timeformat: '%Y-%m-%d %H:%M' +version: v2.4.5 diff --git a/tests/features/configs/invalid_color.yaml b/tests/features/configs/invalid_color.yaml new file mode 100644 index 00000000..25c0e58d --- /dev/null +++ b/tests/features/configs/invalid_color.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: not-a-color + title: also-not-a-color + body: still-no-color + tags: me-too diff --git a/tests/features/configs/little_endian_dates.yaml b/tests/features/configs/little_endian_dates.yaml new file mode 100644 index 00000000..223c820d --- /dev/null +++ b/tests/features/configs/little_endian_dates.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/little_endian_dates.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%d.%m.%Y %H:%M" +indent_character: "|" diff --git a/tests/features/configs/markdown-headings-335.yaml b/tests/features/configs/markdown-headings-335.yaml new file mode 100644 index 00000000..4368f641 --- /dev/null +++ b/tests/features/configs/markdown-headings-335.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: false +highlight: true +template: false +journals: + default: features/journals/markdown-headings-335.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/configs/missing_directory.yaml b/tests/features/configs/missing_directory.yaml new file mode 100644 index 00000000..d600404c --- /dev/null +++ b/tests/features/configs/missing_directory.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/missing_directory/simple.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/configs/missing_journal.yaml b/tests/features/configs/missing_journal.yaml new file mode 100644 index 00000000..a1f6f8cf --- /dev/null +++ b/tests/features/configs/missing_journal.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/missing.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/configs/mostlyreadabledates.yaml b/tests/features/configs/mostlyreadabledates.yaml new file mode 100644 index 00000000..5e3e1a15 --- /dev/null +++ b/tests/features/configs/mostlyreadabledates.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/mostlyreadabledates.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/configs/multiline-tags.yaml b/tests/features/configs/multiline-tags.yaml new file mode 100644 index 00000000..033aaa27 --- /dev/null +++ b/tests/features/configs/multiline-tags.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/multiline-tags.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/configs/multiline.yaml b/tests/features/configs/multiline.yaml new file mode 100644 index 00000000..aa35b3f5 --- /dev/null +++ b/tests/features/configs/multiline.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/multiline.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/configs/multiple.yaml b/tests/features/configs/multiple.yaml new file mode 100644 index 00000000..65f2c256 --- /dev/null +++ b/tests/features/configs/multiple.yaml @@ -0,0 +1,18 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: false +highlight: true +template: false +journals: + default: features/journals/simple.journal + ideas: features/journals/nothing.journal + simple: features/journals/simple.journal + work: features/journals/work.journal + new_encrypted: + encrypt: true + journal: features/journals/new_encrypted.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/configs/no_colors.yaml b/tests/features/configs/no_colors.yaml new file mode 100644 index 00000000..9111b561 --- /dev/null +++ b/tests/features/configs/no_colors.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/configs/simple.yaml b/tests/features/configs/simple.yaml new file mode 100644 index 00000000..f8739142 --- /dev/null +++ b/tests/features/configs/simple.yaml @@ -0,0 +1,18 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none +version: v2.5 \ No newline at end of file diff --git a/tests/features/configs/tags-216.yaml b/tests/features/configs/tags-216.yaml new file mode 100644 index 00000000..81b3865f --- /dev/null +++ b/tests/features/configs/tags-216.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: false +highlight: true +template: false +journals: + default: features/journals/tags-216.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/configs/tags-237.yaml b/tests/features/configs/tags-237.yaml new file mode 100644 index 00000000..5aecd61e --- /dev/null +++ b/tests/features/configs/tags-237.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: false +highlight: true +template: false +journals: + default: features/journals/tags-237.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/configs/tags.yaml b/tests/features/configs/tags.yaml new file mode 100644 index 00000000..4b55952c --- /dev/null +++ b/tests/features/configs/tags.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: false +highlight: true +template: false +journals: + default: features/journals/tags.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/configs/unreadabledates.yaml b/tests/features/configs/unreadabledates.yaml new file mode 100644 index 00000000..99304e5a --- /dev/null +++ b/tests/features/configs/unreadabledates.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/unreadabledates.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/configs/upgrade_from_195.json b/tests/features/configs/upgrade_from_195.json new file mode 100644 index 00000000..ec380372 --- /dev/null +++ b/tests/features/configs/upgrade_from_195.json @@ -0,0 +1,11 @@ +{ +"default_hour": 9, +"timeformat": "%Y-%m-%d %H:%M", +"linewrap": 80, +"encrypt": false, +"editor": "", +"default_minute": 0, +"highlight": true, +"journals": {"default": "features/journals/simple_jrnl-1-9-5.journal"}, +"tagsymbols": "@" +} diff --git a/tests/features/configs/upgrade_from_195_little_endian_dates.json b/tests/features/configs/upgrade_from_195_little_endian_dates.json new file mode 100644 index 00000000..7d3c470c --- /dev/null +++ b/tests/features/configs/upgrade_from_195_little_endian_dates.json @@ -0,0 +1,11 @@ +{ +"default_hour": 9, +"timeformat": "%d.%m.%Y %H:%M", +"linewrap": 80, +"encrypt": false, +"editor": "", +"default_minute": 0, +"highlight": true, +"journals": {"default": "features/journals/simple_jrnl-1-9-5_little_endian_dates.journal"}, +"tagsymbols": "@" +} diff --git a/tests/features/configs/upgrade_from_195_with_missing_encrypted_journal.json b/tests/features/configs/upgrade_from_195_with_missing_encrypted_journal.json new file mode 100644 index 00000000..5bbfb5b1 --- /dev/null +++ b/tests/features/configs/upgrade_from_195_with_missing_encrypted_journal.json @@ -0,0 +1,11 @@ +{ +"default_hour": 9, +"timeformat": "%Y-%m-%d %H:%M", +"linewrap": 80, +"encrypt": true, +"editor": "", +"default_minute": 0, +"highlight": true, +"journals": {"default": "features/journals/encrypted_jrnl-1-9-5.journal", "missing": "features/journals/missing.journal"}, +"tagsymbols": "@" +} diff --git a/tests/features/configs/upgrade_from_195_with_missing_journal.json b/tests/features/configs/upgrade_from_195_with_missing_journal.json new file mode 100644 index 00000000..8d456159 --- /dev/null +++ b/tests/features/configs/upgrade_from_195_with_missing_journal.json @@ -0,0 +1,11 @@ +{ +"default_hour": 9, +"timeformat": "%Y-%m-%d %H:%M", +"linewrap": 80, +"encrypt": false, +"editor": "", +"default_minute": 0, +"highlight": true, +"journals": {"default": "features/journals/simple_jrnl-1-9-5.journal", "missing": "features/journals/missing.journal"}, +"tagsymbols": "@" +} diff --git a/tests/features/core.feature b/tests/features/core.feature new file mode 100644 index 00000000..3115fd57 --- /dev/null +++ b/tests/features/core.feature @@ -0,0 +1,7 @@ +Feature: Functionality of jrnl outside of actually handling journals + + Scenario: Displaying the version number + Given we use the config "simple.yaml" + When we run "jrnl --version" + Then we should get no error + Then the output should match "^jrnl version v\d+\.\d+(\.\d+)?(-(alpha|beta)\d*)?" diff --git a/tests/features/data/configs/basic_dayone.yaml b/tests/features/data/configs/basic_dayone.yaml new file mode 100644 index 00000000..0209f2f7 --- /dev/null +++ b/tests/features/data/configs/basic_dayone.yaml @@ -0,0 +1,17 @@ +colors: + date: none + title: none + body: none + tags: none +default_hour: 9 +default_minute: 0 +editor: noop +encrypt: false +highlight: true +journals: + default: features/journals/basic_dayone.dayone +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/data/configs/basic_encrypted.yaml b/tests/features/data/configs/basic_encrypted.yaml new file mode 100644 index 00000000..77f4e48d --- /dev/null +++ b/tests/features/data/configs/basic_encrypted.yaml @@ -0,0 +1,17 @@ +colors: + date: none + title: none + body: none + tags: none +default_hour: 9 +default_minute: 0 +editor: noop +encrypt: true +highlight: true +journals: + default: features/journals/basic_encrypted.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/data/configs/basic_folder.yaml b/tests/features/data/configs/basic_folder.yaml new file mode 100644 index 00000000..ba0de638 --- /dev/null +++ b/tests/features/data/configs/basic_folder.yaml @@ -0,0 +1,17 @@ +colors: + date: none + title: none + body: none + tags: none +default_hour: 9 +default_minute: 0 +editor: noop +encrypt: false +highlight: true +journals: + default: features/journals/basic_folder +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/data/configs/basic_onefile.yaml b/tests/features/data/configs/basic_onefile.yaml new file mode 100644 index 00000000..fb48c6f8 --- /dev/null +++ b/tests/features/data/configs/basic_onefile.yaml @@ -0,0 +1,17 @@ +colors: + date: none + title: none + body: none + tags: none +default_hour: 9 +default_minute: 0 +editor: noop +encrypt: false +highlight: true +journals: + default: features/journals/basic_onefile.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/data/configs/brackets.yaml b/tests/features/data/configs/brackets.yaml new file mode 100644 index 00000000..e658947c --- /dev/null +++ b/tests/features/data/configs/brackets.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/brackets.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/data/configs/bug153.yaml b/tests/features/data/configs/bug153.yaml new file mode 100644 index 00000000..ff645ab6 --- /dev/null +++ b/tests/features/data/configs/bug153.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: false +highlight: true +journals: + default: features/journals/bug153.dayone +linewrap: 80 +tagsymbols: '@' +template: false +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/data/configs/bug343.yaml b/tests/features/data/configs/bug343.yaml new file mode 100644 index 00000000..a4e25d8a --- /dev/null +++ b/tests/features/data/configs/bug343.yaml @@ -0,0 +1,13 @@ +default_hour: 9 +default_minute: 0 +editor: '' +template: false +encrypt: false +highlight: true +journals: + simple: features/journals/simple.journal + work: features/journals/work.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/data/configs/bug780.yaml b/tests/features/data/configs/bug780.yaml new file mode 100644 index 00000000..e1d830c2 --- /dev/null +++ b/tests/features/data/configs/bug780.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: false +highlight: true +journals: + default: features/journals/bug780.dayone +linewrap: 80 +tagsymbols: '@' +template: false +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/data/configs/dayone.yaml b/tests/features/data/configs/dayone.yaml new file mode 100644 index 00000000..894cb911 --- /dev/null +++ b/tests/features/data/configs/dayone.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: noop +template: false +encrypt: false +highlight: true +journals: + default: features/journals/dayone.dayone +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/data/configs/dayone_empty.yaml b/tests/features/data/configs/dayone_empty.yaml new file mode 100644 index 00000000..7750d389 --- /dev/null +++ b/tests/features/data/configs/dayone_empty.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: noop +template: false +encrypt: false +highlight: true +journals: + default: features/journals/dayone_empty.dayone +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/data/configs/deletion.yaml b/tests/features/data/configs/deletion.yaml new file mode 100644 index 00000000..d4155260 --- /dev/null +++ b/tests/features/data/configs/deletion.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/deletion.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/data/configs/deletion_filters.yaml b/tests/features/data/configs/deletion_filters.yaml new file mode 100644 index 00000000..73a88e4d --- /dev/null +++ b/tests/features/data/configs/deletion_filters.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/deletion_filters.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/data/configs/editor-args.yaml b/tests/features/data/configs/editor-args.yaml new file mode 100644 index 00000000..12c5bd9c --- /dev/null +++ b/tests/features/data/configs/editor-args.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: vim -f -c 'setf markdown' +encrypt: false +highlight: true +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/data/configs/editor.yaml b/tests/features/data/configs/editor.yaml new file mode 100644 index 00000000..8a06f916 --- /dev/null +++ b/tests/features/data/configs/editor.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "vim" +encrypt: false +highlight: true +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/data/configs/editor_empty_folder.yaml b/tests/features/data/configs/editor_empty_folder.yaml new file mode 100644 index 00000000..1724bbfb --- /dev/null +++ b/tests/features/data/configs/editor_empty_folder.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: 'vim' +template: false +encrypt: false +highlight: true +journals: + default: features/journals/empty_folder +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/data/configs/editor_encrypted.yaml b/tests/features/data/configs/editor_encrypted.yaml new file mode 100644 index 00000000..75273c96 --- /dev/null +++ b/tests/features/data/configs/editor_encrypted.yaml @@ -0,0 +1,17 @@ +colors: + body: green + date: blue + tags: none + title: yellow +default_hour: 9 +default_minute: 0 +editor: "vim" +encrypt: true +template: false +highlight: true +journals: + default: features/journals/encrypted.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/data/configs/empty_folder.yaml b/tests/features/data/configs/empty_folder.yaml new file mode 100644 index 00000000..52a21854 --- /dev/null +++ b/tests/features/data/configs/empty_folder.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: '' +template: false +encrypt: false +highlight: true +journals: + default: features/journals/empty_folder +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/data/configs/encrypted.yaml b/tests/features/data/configs/encrypted.yaml new file mode 100644 index 00000000..4d50b607 --- /dev/null +++ b/tests/features/data/configs/encrypted.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: true +template: false +highlight: true +journals: + default: features/journals/encrypted.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/data/configs/encrypted_old.json b/tests/features/data/configs/encrypted_old.json new file mode 100644 index 00000000..e69d9b79 --- /dev/null +++ b/tests/features/data/configs/encrypted_old.json @@ -0,0 +1,13 @@ +{ + "default_hour": 9, + "default_minute": 0, + "editor": "", + "encrypt": true, + "highlight": true, + "journals": { + "default": "features/journals/encrypted_jrnl-1-9-5.journal" + }, + "linewrap": 80, + "tagsymbols": "@", + "timeformat": "%Y-%m-%d %H:%M" +} diff --git a/tests/features/data/configs/encrypted_old.yaml b/tests/features/data/configs/encrypted_old.yaml new file mode 100644 index 00000000..bc7b1440 --- /dev/null +++ b/tests/features/data/configs/encrypted_old.yaml @@ -0,0 +1,11 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: true +highlight: true +journals: + default: features/journals/encrypted_jrnl1-9-5.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/data/configs/format_md.yaml b/tests/features/data/configs/format_md.yaml new file mode 100644 index 00000000..0b9f1c3b --- /dev/null +++ b/tests/features/data/configs/format_md.yaml @@ -0,0 +1,19 @@ +colors: + body: none + date: none + tags: none + title: none +default_hour: 9 +default_minute: 0 +display_format: markdown +editor: '' +encrypt: false +highlight: true +indent_character: '|' +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: '@' +template: false +timeformat: '%Y-%m-%d %H:%M' +version: v2.4.5 diff --git a/tests/features/data/configs/format_text.yaml b/tests/features/data/configs/format_text.yaml new file mode 100644 index 00000000..c82ff7a7 --- /dev/null +++ b/tests/features/data/configs/format_text.yaml @@ -0,0 +1,19 @@ +colors: + body: none + date: none + tags: none + title: none +default_hour: 9 +default_minute: 0 +display_format: text +editor: '' +encrypt: false +highlight: true +indent_character: '|' +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: '@' +template: false +timeformat: '%Y-%m-%d %H:%M' +version: v2.4.5 diff --git a/tests/features/data/configs/invalid_color.yaml b/tests/features/data/configs/invalid_color.yaml new file mode 100644 index 00000000..25c0e58d --- /dev/null +++ b/tests/features/data/configs/invalid_color.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: not-a-color + title: also-not-a-color + body: still-no-color + tags: me-too diff --git a/tests/features/data/configs/little_endian_dates.yaml b/tests/features/data/configs/little_endian_dates.yaml new file mode 100644 index 00000000..223c820d --- /dev/null +++ b/tests/features/data/configs/little_endian_dates.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/little_endian_dates.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%d.%m.%Y %H:%M" +indent_character: "|" diff --git a/tests/features/data/configs/markdown-headings-335.yaml b/tests/features/data/configs/markdown-headings-335.yaml new file mode 100644 index 00000000..4368f641 --- /dev/null +++ b/tests/features/data/configs/markdown-headings-335.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: false +highlight: true +template: false +journals: + default: features/journals/markdown-headings-335.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/data/configs/missing_directory.yaml b/tests/features/data/configs/missing_directory.yaml new file mode 100644 index 00000000..d600404c --- /dev/null +++ b/tests/features/data/configs/missing_directory.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/missing_directory/simple.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/data/configs/missing_journal.yaml b/tests/features/data/configs/missing_journal.yaml new file mode 100644 index 00000000..a1f6f8cf --- /dev/null +++ b/tests/features/data/configs/missing_journal.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/missing.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/data/configs/mostlyreadabledates.yaml b/tests/features/data/configs/mostlyreadabledates.yaml new file mode 100644 index 00000000..5e3e1a15 --- /dev/null +++ b/tests/features/data/configs/mostlyreadabledates.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/mostlyreadabledates.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/data/configs/multiline-tags.yaml b/tests/features/data/configs/multiline-tags.yaml new file mode 100644 index 00000000..033aaa27 --- /dev/null +++ b/tests/features/data/configs/multiline-tags.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/multiline-tags.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/data/configs/multiline.yaml b/tests/features/data/configs/multiline.yaml new file mode 100644 index 00000000..aa35b3f5 --- /dev/null +++ b/tests/features/data/configs/multiline.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/multiline.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/data/configs/multiple.yaml b/tests/features/data/configs/multiple.yaml new file mode 100644 index 00000000..65f2c256 --- /dev/null +++ b/tests/features/data/configs/multiple.yaml @@ -0,0 +1,18 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: false +highlight: true +template: false +journals: + default: features/journals/simple.journal + ideas: features/journals/nothing.journal + simple: features/journals/simple.journal + work: features/journals/work.journal + new_encrypted: + encrypt: true + journal: features/journals/new_encrypted.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" diff --git a/tests/features/data/configs/no_colors.yaml b/tests/features/data/configs/no_colors.yaml new file mode 100644 index 00000000..9111b561 --- /dev/null +++ b/tests/features/data/configs/no_colors.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/tests/features/data/configs/simple.yaml b/tests/features/data/configs/simple.yaml new file mode 100644 index 00000000..020bab18 --- /dev/null +++ b/tests/features/data/configs/simple.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/data/configs/tags-216.yaml b/tests/features/data/configs/tags-216.yaml new file mode 100644 index 00000000..81b3865f --- /dev/null +++ b/tests/features/data/configs/tags-216.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: false +highlight: true +template: false +journals: + default: features/journals/tags-216.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/data/configs/tags-237.yaml b/tests/features/data/configs/tags-237.yaml new file mode 100644 index 00000000..5aecd61e --- /dev/null +++ b/tests/features/data/configs/tags-237.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: false +highlight: true +template: false +journals: + default: features/journals/tags-237.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/data/configs/tags.yaml b/tests/features/data/configs/tags.yaml new file mode 100644 index 00000000..4b55952c --- /dev/null +++ b/tests/features/data/configs/tags.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: '' +encrypt: false +highlight: true +template: false +journals: + default: features/journals/tags.journal +linewrap: 80 +tagsymbols: '@' +timeformat: '%Y-%m-%d %H:%M' +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/data/configs/unreadabledates.yaml b/tests/features/data/configs/unreadabledates.yaml new file mode 100644 index 00000000..99304e5a --- /dev/null +++ b/tests/features/data/configs/unreadabledates.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/unreadabledates.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/tests/features/data/configs/upgrade_from_195.json b/tests/features/data/configs/upgrade_from_195.json new file mode 100644 index 00000000..ec380372 --- /dev/null +++ b/tests/features/data/configs/upgrade_from_195.json @@ -0,0 +1,11 @@ +{ +"default_hour": 9, +"timeformat": "%Y-%m-%d %H:%M", +"linewrap": 80, +"encrypt": false, +"editor": "", +"default_minute": 0, +"highlight": true, +"journals": {"default": "features/journals/simple_jrnl-1-9-5.journal"}, +"tagsymbols": "@" +} diff --git a/tests/features/data/configs/upgrade_from_195_little_endian_dates.json b/tests/features/data/configs/upgrade_from_195_little_endian_dates.json new file mode 100644 index 00000000..7d3c470c --- /dev/null +++ b/tests/features/data/configs/upgrade_from_195_little_endian_dates.json @@ -0,0 +1,11 @@ +{ +"default_hour": 9, +"timeformat": "%d.%m.%Y %H:%M", +"linewrap": 80, +"encrypt": false, +"editor": "", +"default_minute": 0, +"highlight": true, +"journals": {"default": "features/journals/simple_jrnl-1-9-5_little_endian_dates.journal"}, +"tagsymbols": "@" +} diff --git a/tests/features/data/configs/upgrade_from_195_with_missing_encrypted_journal.json b/tests/features/data/configs/upgrade_from_195_with_missing_encrypted_journal.json new file mode 100644 index 00000000..5bbfb5b1 --- /dev/null +++ b/tests/features/data/configs/upgrade_from_195_with_missing_encrypted_journal.json @@ -0,0 +1,11 @@ +{ +"default_hour": 9, +"timeformat": "%Y-%m-%d %H:%M", +"linewrap": 80, +"encrypt": true, +"editor": "", +"default_minute": 0, +"highlight": true, +"journals": {"default": "features/journals/encrypted_jrnl-1-9-5.journal", "missing": "features/journals/missing.journal"}, +"tagsymbols": "@" +} diff --git a/tests/features/data/configs/upgrade_from_195_with_missing_journal.json b/tests/features/data/configs/upgrade_from_195_with_missing_journal.json new file mode 100644 index 00000000..8d456159 --- /dev/null +++ b/tests/features/data/configs/upgrade_from_195_with_missing_journal.json @@ -0,0 +1,11 @@ +{ +"default_hour": 9, +"timeformat": "%Y-%m-%d %H:%M", +"linewrap": 80, +"encrypt": false, +"editor": "", +"default_minute": 0, +"highlight": true, +"journals": {"default": "features/journals/simple_jrnl-1-9-5.journal", "missing": "features/journals/missing.journal"}, +"tagsymbols": "@" +} diff --git a/tests/features/data/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry b/tests/features/data/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry new file mode 100644 index 00000000..9721dd55 --- /dev/null +++ b/tests/features/data/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry @@ -0,0 +1,53 @@ + + + + + Creation Date + 2020-08-29T18:11:00Z + Starred + + Entry Text + Entry the first. +Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada +quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque +augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu +consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In +commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget +venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. + +Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo +ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse +potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget +molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus +hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis +feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum +urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget +velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac +porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per +conubia nostra, per inceptos himenaeos. + Time Zone + America/Los_Angeles + UUID + D04D335AFED711EABA18FAFFC2100C3D + Tags + + ipsum + tagone + tagtwo + + Creator + + Device Agent + + Generation Date + 2020-09-25T02:35:45Z + Host Name + iris.lan + OS Agent + Darwin/19.3.0 + Software Agent + jrnl/v2.4.5 + + + diff --git a/tests/features/data/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry b/tests/features/data/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry new file mode 100644 index 00000000..8c2f3c52 --- /dev/null +++ b/tests/features/data/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry @@ -0,0 +1,55 @@ + + + + + Creation Date + 2020-08-31T21:32:00Z + Starred + + Entry Text + A second entry in what I hope to be a long series. +Sed sit amet metus et sapien feugiat elementum. Aliquam bibendum lobortis leo +vitae tempus. Donec eleifend nec mi non volutpat. Lorem ipsum dolor sit amet, +consectetur adipiscing elit. Praesent ut sodales libero. Maecenas nisl lorem, +vestibulum in tempus sit amet, fermentum ut arcu. Donec vel vestibulum lectus, +eget pretium enim. Maecenas diam nunc, imperdiet vitae pharetra sed, pretium id +lectus. Donec eu metus et turpis tempor tristique ac non ex. In tellus arcu, +egestas at efficitur et, ultrices vel est. Sed commodo et nibh non elementum. +Mauris tempus vitae neque vel viverra. @tagtwo all by its lonesome. + +Nulla mattis elementum magna, viverra pretium dui fermentum et. Cras vel +vestibulum odio. Quisque sit amet turpis et urna finibus maximus. Interdum et +malesuada fames ac ante ipsum primis in faucibus. Fusce porttitor iaculis sem, +non dictum ipsum varius nec. Nulla eu erat at risus gravida blandit non vel +ante. Nam egestas ipsum leo, eu ultricies ipsum tincidunt vel. Morbi a commodo +eros. + +Nullam dictum, nisl ac varius tempus, ex tortor fermentum nisl, non +tempus dolor neque a lorem. Suspendisse a faucibus ex, vel ornare tortor. +Maecenas tincidunt id felis quis semper. Pellentesque enim libero, fermentum +quis metus id, rhoncus euismod magna. Nulla finibus velit eu purus bibendum +interdum. Integer id justo dui. Integer eu tellus in turpis bibendum blandit. +Quisque auctor lacinia consectetur. + Time Zone + America/Los_Angeles + UUID + FC8A86CAFED711EA8892FAFFC2100C3D + Tags + + tagtwo + + Creator + + Device Agent + + Generation Date + 2020-09-25T02:36:59Z + Host Name + iris.lan + OS Agent + Darwin/19.3.0 + Software Agent + jrnl/v2.4.5 + + + diff --git a/tests/features/data/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry b/tests/features/data/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry new file mode 100644 index 00000000..d998c36b --- /dev/null +++ b/tests/features/data/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry @@ -0,0 +1,44 @@ + + + + + Creation Date + 2020-09-24T16:14:00Z + Starred + + Entry Text + The third entry finally after weeks without writing. +I'm so excited about emojis. 💯 🎶 💩 + +Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. +Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla +eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis +dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. +Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis +vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. +Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at +ante eget fringilla. @tagthree and also @tagone + Time Zone + America/Los_Angeles + UUID + FD8ABC8EFED711EABC35FAFFC2100C3D + Tags + + tagthree + tagone + + Creator + + Device Agent + + Generation Date + 2020-09-25T02:37:01Z + Host Name + iris.lan + OS Agent + Darwin/19.3.0 + Software Agent + jrnl/v2.4.5 + + + diff --git a/tests/features/data/journals/basic_encrypted.journal b/tests/features/data/journals/basic_encrypted.journal new file mode 100644 index 00000000..ffc122df --- /dev/null +++ b/tests/features/data/journals/basic_encrypted.journal @@ -0,0 +1 @@ +gAAAAABfb4gQBMqqGn_W8v_s7qCi14bX7inuCOKbsBqIUf7_ch14vTUp7lrysPFvhBp5vGijTwDIbk4LKoIISj8NwM31I8L0zEbMx9y6iyF_zseGGNxBvNN0wzAXa67bs-ohiQhhebcdIc_52sltxL2ELh8JAKUaXRwyapgnMgJ7z6deJppLK-B7RE7BiT0eKjWTDMd2x6cZDswvHs9opDp5yjuKWV5m7x6ggCKYgHT3savT9Tg7V0Fq6K3LGWaE59lCrqlAB0u6dnrDX3qcF4SKyckaniXzRShZGebdkUKDcLFun2V2syZwYQN772xjznIsJ16iXicox2uYKg8CnTefsyCwaOZyBvySGEy3CrlBiuIRIcxCtjKbYJ2B-Aq7LZitnBR7Ny_6_Wm8HsBf3N-cFCp4GShiCKrxuXKcOZ7vszG5EKb78JS85bb0mswU5CSdgp6UAHjIZqfJq00qQsViBCbXq3oklCPZXdQkOf5U0KpG2MVUiD-Zcn5Qj3gnUhSEr-5wKU9tWrE63MGPyE6KjZlArZX2W2LeGnW2CEYw9eREGon06AzLJ4mj3BgtjVWLIdGcCwORXvHRjUqazWgbEmXNVTbtp_cKnkW-rFzRBrUoVme9v-1Y3sH0VvHBq7QIj915VzBklzWs1qzIyTPZG5Db9LvdQ7SiV8slf1Jo7l-ayUUdVj6igvKZcgfB4RUHolJoMps5p4lZ5sPqv59KtSa8DCpuoRczIj71OCpuRVARZgy1m5sUD9xSMxOBdy46u1Jnry6iMtzXWI3mEZe5m7UhmW_L4Zcv4bbk8XjkBeHjPdgm2B69jkLmCBFecD5ztoGesCGt_pNo_sWSKqLHV1-coKFB2Nn__a4utU9NJNdeNRkr8_ahU6tn3jmaFjfQ7cKfrXG_NCcYBRX9fja8EQIeBEp_3TCoXQqhuV_bGsNPA2qL63Pt6YiRaUf1g9FNBqJRlKCSOYNixSXQZN_rTePzx0SQ0aIQhADWls62WX-LG5-byJcB6W2P_cH21hDOXkoNEIyLnCz9HQ6Yd6Fbv7298ps3F6jiUDdWES23zv8sDgBuKUN94qSN34j6MDYGFnGI9zsJ-Y-I2frdlLfWPx3pUL7afcKh1nRgXdjctsTSxU2BDrsu03eBz2IoZjoOR0U51IrNMOD1NNT3kctXxHLuOHSEkwAzS3doncQbdRLi5Gc1dQuOUa4sC-p8gVjUKXO-oi_49kp9Km2Ay9wFg0epBbXx2QMzyMsN2dXeSbHF-BDXD6sULaq5syC0fOHqaMLycTCMk2wLfNyXgEt05WvAiDn-LDsRdylMRW2hXp5HWq3Poaul-7VNg6UEMlwVfgJ-7hNreuO6IRtwmx6YdqMscw0ms6mU_MQZU_dTIPg3JU4KL0YyMqPBPSGNCx3gMp41O05Ubir45FoJSnT5Dkj4v3N0S87Ys3HuFLverASsGt9bkcSzd2uMKCJjkspemPPi9VhrY4IOO03DWSWbHmxYzFc1SJ-24WM8Ch404QKpe1qy5LNzFgLvDwQhSIHjluezHXqrD-DVh1lWNNY3WmHI2ubOZfaorvLKqzBPZ6AhpIa60rKjm0OZIQOmJwWXwkdnzut6m8PtoiLzRN897YMgeztf1nmDwp0xE-EhknVZ3WV3TeqgZJ5ykfHQ5BU8x0Db57-UtKSuesKbqPPdBe91OdsPpkGlyl6psHj1_gPm4nLvzXQePwiPaEemR_gYCWGPvl9l1ANJufgCV9qQTmZGof3fb9mjv-9lS-9l_m8KirPPRpSBToNeDtk50ceYUsOlDGzIyusppG9pOcIGyiln1IO5aZ8d4_1E83qjcHTSaKGizICZU7a-pt5STBPMesy3JgBm23A2jO4m68ayBRMcLnw_RirHvvBaj0C6UR2tac45F0Ob3PpXcvFuK0g54ziIAhzGqwF9I-LZ6asXQWMW4y4EBOak8JJBorkfztzfkMaIgGu-4ZoRKOkVfdr4uzcghk3r6KUxD4-nv1ioX69-G5RwhMHppYk7z8RXS1cq5FkvzXbfEQ-Uv6M-sx32DcUy9dH-ZYhc7UWm75JJfiNXLaXT_bsc6VqQ7KPkg2-RA7CywUFCW9S0S-XdO03VdwqlUVo7fp1SKywEfhZv_9bhDCdMJBwZmigv2KP9Iz7fF6LrpLwZkzHuQGFPcyTHFpsVIFrFyJjNYCXpET9y0Q5Vt4fnea5fy-9ZiCt3S8aS0YOFJ35_kM5i3ss8eFPL0v7fIQS3ZilzdGB3bWL0J7kppHN_ekHu-wVk3UZxauoFh7hXLjPcipua-FYUIklLjcK6DG1bYP7_q6OnkC8Jl650FNezeWPomHEv7l_DO3y0tjI6SGdWvL3ZJns7Xp3ew8KsCREAUO7ffqumD03uF9N-9uWbDDjM7rk0vcg0ggfOs9Ni725mxqYpu4R285XCOVWHDvw7iU6eAvE6ry8TDXQBbNgGjTuTYFYYli7GuOqMxFIe1op2s7sRnoJE8O0J76S6APhjhjcnZRSuONWkVG_5o83uFMPSF8DtqLwuRA5E8AGfIwAUcj324sw-DA0ixBGUqomb-osUIisv3x0b044xn-FvD-8R3PZDnPbPsao8XYNxfQWStrNcZSrX2Ua-WAcv9qbQ73_57RKW4pao4ajOu7K5800D231WGiIa6aJzDnFUlzXEzYxFQyx7qegkm_9rrEp_v8TC9mfAcjWX5DMrCkxUskx9YKDfpFYq4NuxO_414gReKzd-lmorfigvttgS10N1XD74SwFluXJv-bqTbI5-SuYAhDGMv1dqrn38i3rOMQqqnQomvaUJRprqxUsKz14sSE1Y-cNqq1FXzZ6vIJq-K3YTfFWPRLeqi6gHzqS_R2YBXXUduKuYgmakiVdP3bWc-Ca8WKh5sVi6P51MO-cS7i9AZWOaOz7F8PsB4JZxAJjSOr3NBmv3EEve9auTFCudRjfC6668I_NMHaTP5CCV4cuhuAxUuKUGgd6WFjDcvoYPyn_lu3bQiqD9MEag4CaJYI9PlraRv5mbqptwxv3pca7usd0GmXN_2No_nwxB4gVb48LsBBkH35njCa5iv2EKXUSOf0k3swaTSEahqbyI4EDzPXtU5uBO39iQzNpgfV_sUpnGdysjqueUVcdWGI_s5CnrNJ-_yDAY06AoXfLrjP8_3NXB2058xZ2rfmTNJNCULz9634dICJReXNnmplxIg3i6GbzFvjfNtqjrWr_iqBShyIwuOUJRbXzdJNggx2BDNG-PEWDXl89SaudFICkDvyZKEcATIss6ZXfULIMfCrqmWmFwgXfNEd9TuvjqoxFlLSaY4UfDMiYa_arUMblFfoo5nV07GANhUoQd-6HRe7LjYeX5VRodOx6ZmZjIAUq-DYr-hatJJFR2tjT_qZht2MJeYT3GZ3o54m8zBBt0JTN7HVpKaOaM3A2hEM_Ah0QZ-DkLDxtCzMuv987GDiLT2-Riya97a47yHIJhZFzFpflW2FcuC8RFWXlfUKTQfZkFmxh3MUekUuS4yu4Z121xojVswk_4P7-FqLaSnGT2epI69I_cvalRx3wjds9-5TFYqf4GridlFBRx6Fv2fpNB9Zvp9k7NQ9oYcPuXGLoXH5kmWBagPhEGKHA_pjFUZmCuwUIoeP4nP8lhFrX8OGezsbSBG773CRJzEdfcgAc5G-p6M_24WZLZHDrsVBAvgrNt6R9eQbEviWU28t_417QCp-or9qqt4OTKv1dp_4MlZh8YBg2-dtpvzSc1l5e4kQFJu7oWlpbgsjB6pl1oRRKp1maedX-gOAf559zC4l85gfEpPln9Cnl6xvERQzfO0Ey4q91SdsgK7i7FBrKKmi2wGiemFvnaQsrjZ_IFujLo8-2c8g9zTiyH1knyoVOAAnQxqGpsz6z6PNfSxr3_G8tOlNFTV-yqN_LdVHMgXtXjn3U9koGsfMulyUcBDdR3d_0Yn6iEjBt77tbxKi2ry-0gQrB1fdGsgKjyE_tMrW8D_lQz0IXsVOzd2ixsFVXMFzD6OOD8JldV0FbA-VDAS-Tp_ezIZVp6lRq54XBgvsjzDyOmOgDbSOQN6SQmvxPnIsml1wgmtm80z-9gHBqmimHBtLKB6L7CtLmmPICMS2pX3eWOmakxscxqs8AVjijJdz_NYNfcdBeDj_fhm6dqD6iwk3EBZZfsrmMGdXtAMqf1r9ng9tsz-FriXwQiJ3IM3loBsk5DKr9CcaJtKSPuwDDlRynD2vwcD-XyF6YTQdSJa9fEcq-qXya2Scj4mqQ4RDemJgErdradRfwJfII3fWHh18XxmYVqi9Bwn3YRgwEadyo0-HjbNq6vJXi12igmP99ciRAfMVQLjfUfTwoOHj44Y2Ru_hPjJcvB6FIn6KLrrCSrZnrshFdFn4L36z1CrS8fbtdvrG3kdZQxsUJnMqttuwKRpLnDWTWkIwj_GRBFrzCFgbwGp1XYhemxggyKVuhZPfyyTIM9rhlPth6eGyrpYfap24Av_mGPRBLnzcjtpGbACGdKQL034kVmI7yENGvmY40KSrWsVG_BE9bSJhx0EptFsT2IxnxbuFD4hGb4fFag9V0BDiKpUoOZqIVqVO8cAp-5w4twvWZKkrhu16JNlLoXWMoFANrw-tp5LKSin1CUeRa4LWVI1GR8tRkIad_GnCHRv9JEMswlNy9wi2sDNsSxWT7WNasUW5-glgK9pR7d2pXGGOWfHj1U6CKIqmAiO3iw8igzhvyx_dAxMxPo \ No newline at end of file diff --git a/tests/features/data/journals/basic_folder/2020/08/29.txt b/tests/features/data/journals/basic_folder/2020/08/29.txt new file mode 100644 index 00000000..c8af54ca --- /dev/null +++ b/tests/features/data/journals/basic_folder/2020/08/29.txt @@ -0,0 +1,19 @@ +[2020-08-29 11:11:00 AM] Entry the first. +Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada +quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque +augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu +consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In +commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget +venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. + +Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo +ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse +potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget +molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus +hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis +feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum +urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget +velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac +porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per +conubia nostra, per inceptos himenaeos. diff --git a/tests/features/data/journals/basic_folder/2020/08/31.txt b/tests/features/data/journals/basic_folder/2020/08/31.txt new file mode 100644 index 00000000..826e7cdb --- /dev/null +++ b/tests/features/data/journals/basic_folder/2020/08/31.txt @@ -0,0 +1,23 @@ +[2020-08-31 02:32:00 PM] A second entry in what I hope to be a long series. * +Sed sit amet metus et sapien feugiat elementum. Aliquam bibendum lobortis leo +vitae tempus. Donec eleifend nec mi non volutpat. Lorem ipsum dolor sit amet, +consectetur adipiscing elit. Praesent ut sodales libero. Maecenas nisl lorem, +vestibulum in tempus sit amet, fermentum ut arcu. Donec vel vestibulum lectus, +eget pretium enim. Maecenas diam nunc, imperdiet vitae pharetra sed, pretium id +lectus. Donec eu metus et turpis tempor tristique ac non ex. In tellus arcu, +egestas at efficitur et, ultrices vel est. Sed commodo et nibh non elementum. +Mauris tempus vitae neque vel viverra. @tagtwo all by its lonesome. + +Nulla mattis elementum magna, viverra pretium dui fermentum et. Cras vel +vestibulum odio. Quisque sit amet turpis et urna finibus maximus. Interdum et +malesuada fames ac ante ipsum primis in faucibus. Fusce porttitor iaculis sem, +non dictum ipsum varius nec. Nulla eu erat at risus gravida blandit non vel +ante. Nam egestas ipsum leo, eu ultricies ipsum tincidunt vel. Morbi a commodo +eros. + +Nullam dictum, nisl ac varius tempus, ex tortor fermentum nisl, non +tempus dolor neque a lorem. Suspendisse a faucibus ex, vel ornare tortor. +Maecenas tincidunt id felis quis semper. Pellentesque enim libero, fermentum +quis metus id, rhoncus euismod magna. Nulla finibus velit eu purus bibendum +interdum. Integer id justo dui. Integer eu tellus in turpis bibendum blandit. +Quisque auctor lacinia consectetur. diff --git a/tests/features/data/journals/basic_folder/2020/09/24.txt b/tests/features/data/journals/basic_folder/2020/09/24.txt new file mode 100644 index 00000000..2bd885ce --- /dev/null +++ b/tests/features/data/journals/basic_folder/2020/09/24.txt @@ -0,0 +1,11 @@ +[2020-09-24 09:14:00 AM] The third entry finally after weeks without writing. +I'm so excited about emojis. 💯 🎶 💩 + +Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. +Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla +eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis +dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. +Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis +vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. +Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at +ante eget fringilla. @tagthree and also @tagone diff --git a/tests/features/data/journals/basic_onefile.journal b/tests/features/data/journals/basic_onefile.journal new file mode 100644 index 00000000..0d988049 --- /dev/null +++ b/tests/features/data/journals/basic_onefile.journal @@ -0,0 +1,58 @@ +[2020-08-29 11:11] Entry the first. + +Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada +quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque +augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu +consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In +commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget +venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. + +Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo +ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse +potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget +molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus +hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis +feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum +urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget +velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac +porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per +conubia nostra, per inceptos himenaeos. + +[2020-08-31 14:32] A second entry in what I hope to be a long series. * + +Sed sit amet metus et sapien feugiat elementum. Aliquam bibendum lobortis leo +vitae tempus. Donec eleifend nec mi non volutpat. Lorem ipsum dolor sit amet, +consectetur adipiscing elit. Praesent ut sodales libero. Maecenas nisl lorem, +vestibulum in tempus sit amet, fermentum ut arcu. Donec vel vestibulum lectus, +eget pretium enim. Maecenas diam nunc, imperdiet vitae pharetra sed, pretium id +lectus. Donec eu metus et turpis tempor tristique ac non ex. In tellus arcu, +egestas at efficitur et, ultrices vel est. Sed commodo et nibh non elementum. +Mauris tempus vitae neque vel viverra. @tagtwo all by its lonesome. + +Nulla mattis elementum magna, viverra pretium dui fermentum et. Cras vel +vestibulum odio. Quisque sit amet turpis et urna finibus maximus. Interdum et +malesuada fames ac ante ipsum primis in faucibus. Fusce porttitor iaculis sem, +non dictum ipsum varius nec. Nulla eu erat at risus gravida blandit non vel +ante. Nam egestas ipsum leo, eu ultricies ipsum tincidunt vel. Morbi a commodo +eros. + +Nullam dictum, nisl ac varius tempus, ex tortor fermentum nisl, non +tempus dolor neque a lorem. Suspendisse a faucibus ex, vel ornare tortor. +Maecenas tincidunt id felis quis semper. Pellentesque enim libero, fermentum +quis metus id, rhoncus euismod magna. Nulla finibus velit eu purus bibendum +interdum. Integer id justo dui. Integer eu tellus in turpis bibendum blandit. +Quisque auctor lacinia consectetur. + +[2020-09-24 09:14] The third entry finally after weeks without writing. + +I'm so excited about emojis. 💯 🎶 💩 + +Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. +Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla +eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis +dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. +Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis +vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. +Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at +ante eget fringilla. @tagthree and also @tagone diff --git a/tests/features/data/journals/brackets.journal b/tests/features/data/journals/brackets.journal new file mode 100644 index 00000000..4649ea3e --- /dev/null +++ b/tests/features/data/journals/brackets.journal @@ -0,0 +1,2 @@ +[2019-07-08 05:42] Entry subject +[1] line starting with 1 diff --git a/tests/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry b/tests/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry new file mode 100644 index 00000000..066821bb --- /dev/null +++ b/tests/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry @@ -0,0 +1,56 @@ + + + + + Creation Date + 2013-10-27T02:27:27Z + Creator + + Device Agent + iPhone/iPhone3,1 + Generation Date + 2013-10-27T07:02:27Z + Host Name + omrt104001 + OS Agent + iOS/7.0.3 + Software Agent + Day One (iOS)/1.11.4 + + Entry Text + Some text. + Location + + Administrative Area + Östergötlands län + Country + Sverige + Latitude + 58.383400000000000 + Locality + City + Longitude + 15.577170000000000 + Place Name + Street + + Starred + + Time Zone + Europe/Stockholm + UUID + B40EE704E15846DE8D45C44118A4D511 + Weather + + Celsius + 12 + Description + Clear + Fahrenheit + 54 + IconName + sunnyn.png + + + diff --git a/tests/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry b/tests/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry new file mode 100644 index 00000000..ea3efec5 --- /dev/null +++ b/tests/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry @@ -0,0 +1,52 @@ + + Creation Date + 2013-10-27T02:27:27Z + Creator + + Device Agent + iPhone/iPhone3,1 + Generation Date + 2013-10-27T07:02:27Z + Host Name + omrt104001 + OS Agent + iOS/7.0.3 + Software Agent + Day One (iOS)/1.11.4 + + Entry Text + This is not a valid plist. + Location + + Administrative Area + Östergötlands län + Country + Sverige + Latitude + 58.383400000000000 + Locality + City + Longitude + 15.577170000000000 + Place Name + Street + + Starred + + Time Zone + Europe/Stockholm + UUID + B40EE704E15846DE8D45C44118A4D511 + Weather + + Celsius + 12 + Description + Clear + Fahrenheit + 54 + IconName + sunnyn.png + + + diff --git a/tests/features/data/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry b/tests/features/data/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry new file mode 100644 index 00000000..426f1ea8 --- /dev/null +++ b/tests/features/data/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry @@ -0,0 +1,33 @@ + + + + + Activity + Stationary + Creation Date + 2019-12-30T21:28:54Z + Entry Text + + Starred + + UUID + 48A25033B34047C591160A4480197D8B + Creator + + Device Agent + PC + Generation Date + 2019-12-30T21:28:54Z + Host Name + LE-TREPORT + OS Agent + Microsoft Windows/10 Home + Software Agent + Journaley/2.1 + + Tags + + i_have_no_body + + + diff --git a/tests/features/data/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry b/tests/features/data/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry new file mode 100644 index 00000000..1ac26242 --- /dev/null +++ b/tests/features/data/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry @@ -0,0 +1,34 @@ + + + + + Creation Date + 2013-05-17T18:39:20Z + Creator + + Device Agent + Macintosh/MacBookAir5,2 + Generation Date + 2013-08-17T18:39:20Z + Host Name + Egeria + OS Agent + Mac OS X/10.8.4 + Software Agent + Day One (Mac)/1.8 + + Entry Text + This entry has tags! + Starred + + Tags + + work + PLaY + + Time Zone + America/Los_Angeles + UUID + 044F3747A38546168B572C2E3F217FA2 + + diff --git a/tests/features/data/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry b/tests/features/data/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry new file mode 100644 index 00000000..927de884 --- /dev/null +++ b/tests/features/data/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry @@ -0,0 +1,46 @@ + + + + + Creation Date + 2013-06-17T18:38:29Z + Creator + + Device Agent + Macintosh/MacBookAir5,2 + Generation Date + 2013-08-17T18:38:29Z + Host Name + Egeria + OS Agent + Mac OS X/10.8.4 + Software Agent + Day One (Mac)/1.8 + + Entry Text + This entry has a location. + Location + + Administrative Area + California + Country + Germany + Latitude + 52.4979764 + Locality + Berlin + Longitude + 13.2404758 + Place Name + Abandoned Spy Tower + + Starred + + Tags + + Time Zone + Europe/Berlin + UUID + 0BDDD6CDA43C4A9AA2681517CC35AD9D + + diff --git a/tests/features/data/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry b/tests/features/data/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry new file mode 100644 index 00000000..16260763 --- /dev/null +++ b/tests/features/data/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry @@ -0,0 +1,31 @@ + + + + + Creation Date + 2013-07-17T18:38:08Z + Creator + + Device Agent + Macintosh/MacBookAir5,2 + Generation Date + 2013-08-17T18:38:08Z + Host Name + Egeria + OS Agent + Mac OS X/10.8.4 + Software Agent + Day One (Mac)/1.8 + + Entry Text + This entry is starred! + Starred + + Tags + + Time Zone + America/Los_Angeles + UUID + 422BC895507944A291E6FC44FC6B8BFC + + diff --git a/tests/features/data/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry b/tests/features/data/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry new file mode 100644 index 00000000..9ebaf538 --- /dev/null +++ b/tests/features/data/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry @@ -0,0 +1,29 @@ + + + + + Creation Date + 2013-01-17T18:37:50Z + Creator + + Device Agent + Macintosh/MacBookAir5,2 + Generation Date + 2013-08-17T18:37:50Z + Host Name + Egeria + OS Agent + Mac OS X/10.8.4 + Software Agent + Day One (Mac)/1.8 + + Entry Text + This is a DayOne entry without Timezone. + Starred + + Tags + + UUID + 4BB1F46946AD439996C9B59DE7C4DDC1 + + diff --git a/tests/features/data/journals/dayone_empty.dayone/entries/empty.txt b/tests/features/data/journals/dayone_empty.dayone/entries/empty.txt new file mode 100644 index 00000000..c86b8f66 --- /dev/null +++ b/tests/features/data/journals/dayone_empty.dayone/entries/empty.txt @@ -0,0 +1 @@ +This file exists to preserve the directory structure, but should be ignored by jrnl. diff --git a/tests/features/data/journals/deletion.journal b/tests/features/data/journals/deletion.journal new file mode 100644 index 00000000..c0fa689d --- /dev/null +++ b/tests/features/data/journals/deletion.journal @@ -0,0 +1,5 @@ +[2019-10-29 11:11] First entry. + +[2019-10-29 11:11] Second entry. + +[2019-10-29 11:13] Third entry. \ No newline at end of file diff --git a/tests/features/data/journals/deletion_filters.journal b/tests/features/data/journals/deletion_filters.journal new file mode 100644 index 00000000..9a3747db --- /dev/null +++ b/tests/features/data/journals/deletion_filters.journal @@ -0,0 +1,14 @@ +[2019-10-01 08:00] It's just another day in October. +Not much to write about. + +[2020-01-01 08:00] Happy New Year! +So this is the New Year. @holidays + +[2020-03-01 08:00] It's just another day in March. +A stick, a stone, it's the end of the road. + +[2020-05-01 09:00] Happy May Day! +@holidays @springtime Several holidays fall on this date. + +[2020-05-02 12:10] Writing tests. * +@springtime They will help prevent bugs. diff --git a/tests/features/data/journals/empty_folder/empty b/tests/features/data/journals/empty_folder/empty new file mode 100644 index 00000000..175b82b5 --- /dev/null +++ b/tests/features/data/journals/empty_folder/empty @@ -0,0 +1 @@ +Nothing to see here diff --git a/tests/features/data/journals/encrypted.journal b/tests/features/data/journals/encrypted.journal new file mode 100644 index 00000000..d2a5fcbe --- /dev/null +++ b/tests/features/data/journals/encrypted.journal @@ -0,0 +1 @@ +gAAAAABVIHB7tnwKExG7aC5ZbAbBL9SG2oY2GENeoOJ22i1PZigOvCYvrQN3kpsu0KGr7ay5K-_46R5YFlqJvtQ8anPH2FSITsaZy-l5Lz_5quw3rmzhLwAR1tc0icgtR4MEpXEdsuQ7cyb12Xq-JLDrnATs0id5Vow9Ri_tE7Xe4BXgXaySn3aRPwWKoninVxVPVvETY3MXHSUEXV9OZ-pH5kYBLGYbLA== diff --git a/tests/features/data/journals/encrypted_jrnl-1-9-5.journal b/tests/features/data/journals/encrypted_jrnl-1-9-5.journal new file mode 100644 index 0000000000000000000000000000000000000000..339b47baf9671f4550efeb9b6a0cfcd5032255d6 GIT binary patch literal 128 zcmV-`0Du3(bJIGVsY(mXmoW-2hF&*L`0NbJTYlTUr8*^Qm97}8E^3^1bZ$P^M literal 0 HcmV?d00001 diff --git a/tests/features/data/journals/little_endian_dates.journal b/tests/features/data/journals/little_endian_dates.journal new file mode 100644 index 00000000..d7492969 --- /dev/null +++ b/tests/features/data/journals/little_endian_dates.journal @@ -0,0 +1,5 @@ +[09.06.2013 15:39] My first entry. +Everything is alright + +[10.07.2013 15:40] Life is good. +But I'm better. diff --git a/tests/features/data/journals/markdown-headings-335.journal b/tests/features/data/journals/markdown-headings-335.journal new file mode 100644 index 00000000..30f592ef --- /dev/null +++ b/tests/features/data/journals/markdown-headings-335.journal @@ -0,0 +1,42 @@ +[2015-04-14 13:23] Heading Test + +H1-1 += + +H1-2 +=== + +H1-3 +============================ + +H2-1 +- + +H2-2 +--- + +H2-3 +---------------------------------- + +Horizontal Rules (ignore) + +--- + +=== + +# ATX H1 + +## ATX H2 + +### ATX H3 + +#### ATX H4 + +##### ATX H5 + +###### ATX H6 + +Stuff + +More stuff +more stuff again diff --git a/tests/features/data/journals/mostlyreadabledates.journal b/tests/features/data/journals/mostlyreadabledates.journal new file mode 100644 index 00000000..bd211bf5 --- /dev/null +++ b/tests/features/data/journals/mostlyreadabledates.journal @@ -0,0 +1,8 @@ +[2019-07-18 14:23] Entry subject +Time machines are possible. I know, because I've built one in my garage. + +[2019-07-19 14:23] Entry subject +I'm going to activate the machine. Nobody knows what comes next after this. Or before this? + +[2019-07 14:23] Entry subject +I've crossed so many timelines. Is there any going back? diff --git a/tests/features/data/journals/multiline-tags.journal b/tests/features/data/journals/multiline-tags.journal new file mode 100644 index 00000000..1fb8706f --- /dev/null +++ b/tests/features/data/journals/multiline-tags.journal @@ -0,0 +1,7 @@ +[2013-06-09 15:39] Multiple @line entry with @tags. +Tag with @punctuation. afterwards +@TagOnLineAloneWithOutPunctuation +@TagOnLineAloneWithPunctuation. +Text before @tag. And After. +@hi. Hello +hi Hello \ No newline at end of file diff --git a/tests/features/data/journals/multiline.journal b/tests/features/data/journals/multiline.journal new file mode 100644 index 00000000..294ed141 --- /dev/null +++ b/tests/features/data/journals/multiline.journal @@ -0,0 +1,5 @@ +[2013-06-09 15:39] Multiple line entry. +This is the first line. +This line doesn't have any ending punctuation + +There is a blank line above this. diff --git a/tests/features/data/journals/simple.journal b/tests/features/data/journals/simple.journal new file mode 100644 index 00000000..8336068e --- /dev/null +++ b/tests/features/data/journals/simple.journal @@ -0,0 +1,5 @@ +[2013-06-09 15:39] My first entry. +Everything is alright + +[2013-06-10 15:40] Life is good. +But I'm better. diff --git a/tests/features/data/journals/simple_jrnl-1-9-5.journal b/tests/features/data/journals/simple_jrnl-1-9-5.journal new file mode 100644 index 00000000..7bb6c5ac --- /dev/null +++ b/tests/features/data/journals/simple_jrnl-1-9-5.journal @@ -0,0 +1,13 @@ +2010-06-10 15:00 A life without chocolate is like a bad analogy. + +2013-06-10 15:40 He said "[this] is the best time to be alive". +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada +quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque +augue et venenatis facilisis. + +[2019-08-03 12:55] Some chat log or something + +Suspendisse potenti. Sed dignissim sed nisl eu consequat. Aenean ante ex, +elementum ut interdum et, mattis eget lacus. In commodo nulla nec tellus +placerat, sed ultricies metus bibendum. Duis eget venenatis erat. In at dolor +dui. diff --git a/tests/features/data/journals/simple_jrnl-1-9-5_little_endian_dates.journal b/tests/features/data/journals/simple_jrnl-1-9-5_little_endian_dates.journal new file mode 100644 index 00000000..328b23f4 --- /dev/null +++ b/tests/features/data/journals/simple_jrnl-1-9-5_little_endian_dates.journal @@ -0,0 +1,13 @@ +10.06.2010 15:00 A life without chocolate is like a bad analogy. + +10.06.2013 15:40 He said "[this] is the best time to be alive". +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada +quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque +augue et venenatis facilisis. + +[03.08.2019 12:55] Some chat log or something + +Suspendisse potenti. Sed dignissim sed nisl eu consequat. Aenean ante ex, +elementum ut interdum et, mattis eget lacus. In commodo nulla nec tellus +placerat, sed ultricies metus bibendum. Duis eget venenatis erat. In at dolor +dui. diff --git a/tests/features/data/journals/tags-216.journal b/tests/features/data/journals/tags-216.journal new file mode 100644 index 00000000..08b6d630 --- /dev/null +++ b/tests/features/data/journals/tags-216.journal @@ -0,0 +1,2 @@ +[2013-06-10 15:40] I programmed for @OS/2. +Almost makes me want to go back to @C++, though. (Still better than @C#). diff --git a/tests/features/data/journals/tags-237.journal b/tests/features/data/journals/tags-237.journal new file mode 100644 index 00000000..be050652 --- /dev/null +++ b/tests/features/data/journals/tags-237.journal @@ -0,0 +1,3 @@ +[2014-07-22 11:11] This entry has an email. +@Newline tag should show as a tag. +Kyla's @email is kyla@clevelandunderdog.org and Guinness's is guinness@fortheloveofpits.org. diff --git a/tests/features/data/journals/tags.journal b/tests/features/data/journals/tags.journal new file mode 100644 index 00000000..a28f3159 --- /dev/null +++ b/tests/features/data/journals/tags.journal @@ -0,0 +1,8 @@ +[2013-04-09 15:39] I have an @idea: +(1) write a command line @journal software +(2) ??? +(3) PROFIT! + +[2013-06-10 15:40] I met with @dan. +As alway's he shared his latest @idea on how to rule the world with me. +inst diff --git a/tests/features/data/journals/unreadabledates.journal b/tests/features/data/journals/unreadabledates.journal new file mode 100644 index 00000000..53ef1d60 --- /dev/null +++ b/tests/features/data/journals/unreadabledates.journal @@ -0,0 +1,5 @@ +[ashasd7zdskhz7asdkjasd] Entry subject +I've lost track of time. + +[sadfhakjsdf88sdf7sdff] Entry subject +Time has no meaning. diff --git a/tests/features/data/journals/work.journal b/tests/features/data/journals/work.journal new file mode 100644 index 00000000..e69de29b diff --git a/tests/features/data/templates/sample.template b/tests/features/data/templates/sample.template new file mode 100644 index 00000000..a356d823 --- /dev/null +++ b/tests/features/data/templates/sample.template @@ -0,0 +1,19 @@ +--- +extension: txt +--- + +{% block journal %} +{% for entry in entries %} +{% include entry %} +{% endfor %} + +{% endblock %} + +{% block entry %} +{{ entry.title }} +{{ "-" * len(entry.title) }} + +{{ entry.body }} + +{% endblock %} +` diff --git a/tests/features/datetime.feature b/tests/features/datetime.feature new file mode 100644 index 00000000..8fe335c9 --- /dev/null +++ b/tests/features/datetime.feature @@ -0,0 +1,155 @@ +Feature: Reading and writing to journal with custom date formats + + Scenario: Dates can include a time + # https://github.com/jrnl-org/jrnl/issues/117 + Given we use the config "simple.yaml" + When we run "jrnl 2013-11-30 15:42: Project Started." + Then we should see the message "Entry added" + And the journal should contain "[2013-11-30 15:42] Project Started." + + Scenario: Dates can be in the future + # https://github.com/jrnl-org/jrnl/issues/185 + Given we use the config "simple.yaml" + When we run "jrnl 26/06/2099: Planet? Earth. Year? 2099." + Then we should see the message "Entry added" + And the journal should contain "[2099-06-26 09:00] Planet?" + + Scenario: Loading a sample journal with custom date + Given we use the config "little_endian_dates.yaml" + When we run "jrnl -n 2" + Then we should get no error + And the output should be + """ + 09.06.2013 15:39 My first entry. + | Everything is alright + + 10.07.2013 15:40 Life is good. + | But I'm better. + """ + + Scenario Outline: Writing an entry from command line with custom date + Given we use the config ".yaml" + When we run "jrnl " + Then we should see the message "Entry added" + When we run "jrnl -n 1" + Then the output should contain "" + + Examples: Day-first Dates + | config | input | output | + | little_endian_dates | 2020-09-19: My first entry. | 19.09.2020 09:00 My first entry. | + | little_endian_dates | 2020-08-09: My second entry. | 09.08.2020 09:00 My second entry. | + | little_endian_dates | 2020-02-29: Test. | 29.02.2020 09:00 Test. | + | little_endian_dates | 2019-02-29: Test. | 2019-02-29: Test. | + | little_endian_dates | 2020-08-32: Test. | 2020-08-32: Test. | + | little_endian_dates | 2032-02-01: Test. | 01.02.2032 09:00 Test. | + | little_endian_dates | 2020-01-01: Test. | 01.01.2020 09:00 Test. | + | little_endian_dates | 2020-12-31: Test. | 31.12.2020 09:00 Test. | + + Scenario Outline: Searching for dates with custom date + Given we use the config ".yaml" + When we run "jrnl -on '' --short" + Then the output should be "" + + Examples: Day-first Dates + | config | input | output | + | little_endian_dates | 2013-07-10 | 10.07.2013 15:40 Life is good. | + | little_endian_dates | june 9 2013 | 09.06.2013 15:39 My first entry. | + | little_endian_dates | july 10 2013 | 10.07.2013 15:40 Life is good. | + | little_endian_dates | june 2013 | 09.06.2013 15:39 My first entry. | + | little_endian_dates | july 2013 | 10.07.2013 15:40 Life is good. | + # @todo month alone with no year should work + # | little_endian_dates | june | 09.06.2013 15:39 My first entry. | + # | little_endian_dates | july | 10.07.2013 15:40 Life is good. | + + Scenario: Writing an entry at the prompt with custom date + Given we use the config "little_endian_dates.yaml" + When we run "jrnl" and enter "2013-05-10: I saw Elvis. He's alive." + Then we should get no error + And the journal should contain "[10.05.2013 09:00] I saw Elvis." + And the journal should contain "He's alive." + + Scenario: Viewing today's entries does not print the entire journal + # https://github.com/jrnl-org/jrnl/issues/741 + Given we use the config "simple.yaml" + When we run "jrnl -on today" + Then the output should not contain "Life is good" + And the output should not contain "But I'm better." + + Scenario Outline: Create entry using day of the week as entry date. + Given we use the config "simple.yaml" + When we run "jrnl : This is an entry on a ." + Then we should see the message "Entry added" + When we run "jrnl -1" + Then the output should contain " at 9am" in the local time + And the output should contain "This is an entry on a ." + + Examples: Days of the week + | day | + | Monday | + | Tuesday | + | Wednesday | + | Thursday | + | Friday | + | Saturday | + | Sunday | + | sunday | + | sUndAy | + + Scenario Outline: Create entry using day of the week abbreviations as entry date. + Given we use the config "simple.yaml" + When we run "jrnl : This is an entry on a ." + Then we should see the message "Entry added" + When we run "jrnl -1" + Then the output should contain " at 9am" in the local time + + Examples: Days of the week + | day | weekday | + | mon | Monday | + | tue | Tuesday | + | wed | Wednesday | + | thu | Thursday | + | fri | Friday | + | sat | Saturday | + | sun | Sunday | + + Scenario: Journals with unreadable dates should still be loaded + Given we use the config "unreadabledates.yaml" + When we run "jrnl -2" + Then the output should contain "I've lost track of time." + And the output should contain "Time has no meaning." + + Scenario: Journals with readable dates AND unreadable dates should still contain all data. + Given we use the config "mostlyreadabledates.yaml" + When we run "jrnl -3" + Then the output should contain "Time machines are possible." + Then the output should contain "I'm going to activate the machine." + And the output should contain "I've crossed so many timelines. Is there any going back?" + And the journal should have 3 entries + + Scenario: Update near-valid dates after journal is edited + Given we use the config "mostlyreadabledates.yaml" + When we run "jrnl 2222-08-19: I have made it exactly one month into the future." + Then the journal should contain "[2019-07-01 14:23] Entry subject" + + Scenario: Integers in square brackets should not be read as dates + Given we use the config "brackets.yaml" + When we run "jrnl -1" + Then the output should contain "[1] line starting with 1" + + # broken still + @skip + Scenario: Dayone entries without timezone information are interpreted in current timezone + Given we use the config "dayone.yaml" + When we run "jrnl -until 'feb 2013'" + Then we should get no error + And the output should contain "2013-01-17T18:37Z" in the local time + + Scenario: Loading entry with ambiguous time stamp in timezone-aware journal (like Dayone) + #https://github.com/jrnl-org/jrnl/issues/153 + Given we use the config "bug153.yaml" + When we run "jrnl -1" + Then we should get no error + And the output should be + """ + 2013-10-27 03:27 Some text. + """ diff --git a/tests/features/delete.feature b/tests/features/delete.feature new file mode 100644 index 00000000..2fc3f8f7 --- /dev/null +++ b/tests/features/delete.feature @@ -0,0 +1,229 @@ +Feature: Delete entries from journal + Scenario Outline: Delete flag allows deletion of single entry + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl -1" + Then the output should contain "2020-09-24 09:14 The third entry finally" + When we run "jrnl --delete" and enter + """ + N + N + Y + """ + Then we flush the output + When we run "jrnl -99 --short" + Then the output should be + """ + 2020-08-29 11:11 Entry the first. + 2020-08-31 14:32 A second entry in what I hope to be a long series. + """ + + Examples: Configs + | config | + | basic_onefile | + | basic_encrypted | + # | basic_folder | @todo + # | basic_dayone | @todo + + Scenario Outline: Backing out of interactive delete does not change journal + Given we use the config ".yaml" + When we run "jrnl --delete -n 1" and enter + """ + N + """ + Then we flush the output + When we run "jrnl -99 --short" + Then the output should be + """ + 2020-08-29 11:11 Entry the first. + 2020-08-31 14:32 A second entry in what I hope to be a long series. + 2020-09-24 09:14 The third entry finally after weeks without writing. + """ + + Examples: Configs + | config | + | basic_onefile | + | basic_folder | + | basic_dayone | + + + Scenario Outline: Delete flag with nonsense input deletes nothing (issue #932) + Given we use the config ".yaml" + When we run "jrnl --delete asdfasdf" + Then we flush the output + When we run "jrnl -99 --short" + Then the output should be + """ + 2020-08-29 11:11 Entry the first. + 2020-08-31 14:32 A second entry in what I hope to be a long series. + 2020-09-24 09:14 The third entry finally after weeks without writing. + """ + + Examples: Configs + | config | + | basic_onefile | + | basic_folder | + | basic_dayone | + + Scenario Outline: Delete flag with tag only deletes tagged entries + Given we use the config ".yaml" + When we run "jrnl --delete @ipsum" and enter + """ + Y + """ + Then we flush the output + When we run "jrnl -99 --short" + Then the output should be + """ + 2020-08-31 14:32 A second entry in what I hope to be a long series. + 2020-09-24 09:14 The third entry finally after weeks without writing. + """ + + Examples: Configs + | config | + | basic_onefile | + # | basic_folder | @todo + # | basic_dayone | @todo + + + Scenario Outline: Delete flag with multiple tags deletes all entries matching any of the tags + Given we use the config ".yaml" + When we run "jrnl --delete @ipsum @tagthree" and enter + """ + Y + Y + """ + Then we flush the output + When we run "jrnl -99 --short" + Then the output should be + """ + 2020-08-31 14:32 A second entry in what I hope to be a long series. + """ + + Examples: Configs + | config | + | basic_onefile | + # | basic_folder | @todo + # | basic_dayone | @todo + + Scenario Outline: Delete flag with -and deletes boolean AND of tagged entries + Given we use the config ".yaml" + When we run "jrnl --delete -and @tagone @tagtwo" and enter + """ + Y + """ + Then we flush the output + When we run "jrnl -99 --short" + Then the output should be + """ + 2020-08-31 14:32 A second entry in what I hope to be a long series. + 2020-09-24 09:14 The third entry finally after weeks without writing. + """ + + Examples: Configs + | config | + | basic_onefile | + # | basic_folder | @todo + # | basic_dayone | @todo + + Scenario Outline: Delete flag with -not does not delete entries from given tag + Given we use the config ".yaml" + When we run "jrnl --delete @tagone -not @ipsum" and enter + """ + Y + """ + Then we flush the output + When we run "jrnl -99 --short" + Then the output should be + """ + 2020-08-29 11:11 Entry the first. + 2020-08-31 14:32 A second entry in what I hope to be a long series. + """ + + Examples: Configs + | config | + | basic_onefile | + # | basic_folder | @todo + # | basic_dayone | @todo + + Scenario Outline: Delete flag with -from search operator only deletes entries since that date + Given we use the config ".yaml" + When we run "jrnl --delete -from 2020-09-01" and enter + """ + Y + """ + Then we flush the output + When we run "jrnl -99 --short" + Then the output should be + """ + 2020-08-29 11:11 Entry the first. + 2020-08-31 14:32 A second entry in what I hope to be a long series. + """ + + Examples: Configs + | config | + | basic_onefile | + # | basic_folder | @todo + # | basic_dayone | @todo + + Scenario Outline: Delete flag with -to only deletes entries up to specified date + Given we use the config ".yaml" + When we run "jrnl --delete -to 2020-08-31" and enter + """ + Y + Y + """ + Then we flush the output + When we run "jrnl -99 --short" + Then the output should be + """ + 2020-09-24 09:14 The third entry finally after weeks without writing. + """ + + Examples: Configs + | config | + | basic_onefile | + # | basic_folder | @todo + # | basic_dayone | @todo + + + Scenario Outline: Delete flag with -starred only deletes starred entries + Given we use the config ".yaml" + When we run "jrnl --delete -starred" and enter + """ + Y + """ + Then we flush the output + When we run "jrnl -99 --short" + Then the output should be + """ + 2020-08-29 11:11 Entry the first. + 2020-09-24 09:14 The third entry finally after weeks without writing. + """ + + Examples: Configs + | config | + | basic_onefile | + # | basic_folder | @todo + # | basic_dayone | @todo + + Scenario Outline: Delete flag with -contains only entries containing expression + Given we use the config ".yaml" + When we run "jrnl --delete -contains dignissim" and enter + """ + Y + """ + Then we flush the output + When we run "jrnl -99 --short" + Then the output should be + """ + 2020-08-31 14:32 A second entry in what I hope to be a long series. + 2020-09-24 09:14 The third entry finally after weeks without writing. + """ + + Examples: Configs + | config | + | basic_onefile | + # | basic_folder | @todo + # | basic_dayone | @todo + diff --git a/tests/features/encrypt.feature b/tests/features/encrypt.feature new file mode 100644 index 00000000..f2d0a62f --- /dev/null +++ b/tests/features/encrypt.feature @@ -0,0 +1,35 @@ +Feature: Encrypting and decrypting journals + + Scenario: Decrypting a journal + Given we use the config "encrypted.yaml" + When we run "jrnl --decrypt" and enter "bad doggie no biscuit" + Then the config for journal "default" should have "encrypt" set to "bool:False" + And we should see the message "Journal decrypted" + And the journal should have 2 entries + + @todo + Scenario: Trying to decrypt an already unencrypted journal + # This should warn the user that the journal is already encrypted + Given we use the config "simple.yaml" + When we run "jrnl --decrypt" + Then the config for journal "default" should have "encrypt" set to "bool:False" + And the journal should have 2 entries + + @todo + Scenario: Trying to encrypt an already encrypted journal + # This should warn the user that the journal is already encrypted + + Scenario: 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" + And the config for journal "default" should have "encrypt" set to "bool: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" + diff --git a/tests/features/environment.py b/tests/features/environment.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/features/file_storage.feature b/tests/features/file_storage.feature new file mode 100644 index 00000000..33619365 --- /dev/null +++ b/tests/features/file_storage.feature @@ -0,0 +1,56 @@ +Feature: Journals iteracting with the file system in a way that users can see + + Scenario: Adding entries to a Folder journal should generate date files + Given we use the config "empty_folder.yaml" + When we run "jrnl 23 July 2013: Testing folder journal." + Then we should see the message "Entry added" + When the journal directory is listed + Then the output should contain "2013/07/23.txt" or "2013\07\23.txt" + + Scenario: Adding multiple entries to a Folder journal should generate multiple date files + Given we use the config "empty_folder.yaml" + When we run "jrnl 23 July 2013: Testing folder journal." + And we run "jrnl 3/7/2014: Second entry of journal." + Then we should see the message "Entry added" + When the journal directory is listed + Then the output should contain "2013/07/23.txt" or "2013\07\23.txt" + Then the output should contain "2014/03/07.txt" or "2014\03\07.txt" + + Scenario: If the journal and its parent directory don't exist, they should be created + Given we use the config "missing_directory.yaml" + Then the journal should not exist + When we run "jrnl This is a new entry in my journal" + Then the journal should exist + When we run "jrnl -n 1" + Then the output should contain "This is a new entry in my journal" + And the journal should have 1 entry + + Scenario: If the journal file doesn't exist, then it should be created + Given we use the config "missing_journal.yaml" + Then the journal should not exist + When we run "jrnl This is a new entry in my journal" + Then the journal should exist + When we run "jrnl -n 1" + Then the output should contain "This is a new entry in my journal" + And the journal should have 1 entry + + Scenario: Creating journal with relative path should update to absolute path + Given we use the config "missingconfig" + When we run "jrnl hello world" and enter + """ + test.txt + n + """ + And we change directory to "features" + And we run "jrnl -n 1" + Then the output should contain "hello world" + + Scenario: the temporary filename suffix should default to ".jrnl" + Given we use the config "editor.yaml" + When we run "jrnl --edit" + Then the temporary filename suffix should be ".jrnl" + + Scenario: the temporary filename suffix should be "-{template_filename}" + Given we use the config "editor_markdown_extension.yaml" + When we run "jrnl --edit" + Then the temporary filename suffix should be "-extension.md" diff --git a/tests/features/format.feature b/tests/features/format.feature new file mode 100644 index 00000000..4981f685 --- /dev/null +++ b/tests/features/format.feature @@ -0,0 +1,579 @@ +Feature: Custom formats + + Scenario Outline: JSON format + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl --format json" + Then we should get no error + And the output should be parsable as json + And "entries" in the json output should have 3 elements + And "tags" in the json output should contain "@ipsum" + And "tags" in the json output should contain "@tagone" + And "tags" in the json output should contain "@tagthree" + And "tags" in the json output should contain "@tagtwo" + And entry 1 should have an array "tags" with 3 elements + And entry 2 should have an array "tags" with 1 elements + And entry 3 should have an array "tags" with 2 elements + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario: Exporting dayone to json + Given we use the config "dayone.yaml" + When we run "jrnl --export json" + Then we should get no error + And the output should be parsable as json + And the json output should contain entries.0.uuid = "4BB1F46946AD439996C9B59DE7C4DDC1" + + Scenario Outline: Printing a journal that has multiline entries with tags + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl -n 1 @ipsum" + Then we should get no error + And the output should be + """ + 2020-08-29 11:11 Entry the first. + | Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada + | quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus + | pellentesque + | augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu + | consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In + | commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget + | venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. + | + | Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo + | ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse + | potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget + | molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus + | hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis + | feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum + | urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. + | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget + | velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac + | porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per + | conubia nostra, per inceptos himenaeos. + """ + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario Outline: Exporting using filters should only export parts of the journal + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl -until 'August 2020' --format json" + Then the output should be parsable as json + Then we should get no error + And the output should be parsable as json + And "entries" in the json output should have 2 elements + And "tags" in the json output should contain "@ipsum" + And "tags" in the json output should contain "@tagone" + And "tags" in the json output should contain "@tagtwo" + And entry 1 should have an array "tags" with 3 elements + And entry 2 should have an array "tags" with 1 elements + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario Outline: Exporting using custom templates + Given we use the config ".yaml" + And we load template "sample.template" + And we use the password "test" if prompted + When we run "jrnl -1 --format sample" + Then the output should be + """ + The third entry finally after weeks without writing. + ---------------------------------------------------- + + I'm so excited about emojis. 💯 🎶 💩 + + Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. + Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla + eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis + dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. + Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis + vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. + Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at + ante eget fringilla. @tagthree and also @tagone + """ + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario Outline: Increasing Headings on Markdown export + Given we use the config ".yaml" + And we use the password "test" if prompted + When we open the editor and append + """ + [2020-10-14 13:23] Heading Test + + H1-1 + = + + H1-2 + === + + H1-3 + ============================ + + H2-1 + - + + H2-2 + --- + + H2-3 + ---------------------------------- + + Horizontal Rules (ignore) + + --- + + === + + # ATX H1 + + ## ATX H2 + + ### ATX H3 + + #### ATX H4 + + ##### ATX H5 + + ###### ATX H6 + + Stuff + + More stuff + more stuff again + """ + Then we flush the output + When we run "jrnl -1 --export markdown" + Then the output should be + """ + # 2020 + + ## October + + ### 2020-10-14 13:23 Heading Test + + #### H1-1 + + #### H1-2 + + #### H1-3 + + ##### H2-1 + + ##### H2-2 + + ##### H2-3 + + Horizontal Rules (ignore) + + --- + + === + + #### ATX H1 + + ##### ATX H2 + + ###### ATX H3 + + ####### ATX H4 + + ######## ATX H5 + + ######### ATX H6 + + Stuff + + More stuff + more stuff again + """ + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + # | basic_dayone | @todo + + Scenario Outline: Add a blank line to Markdown export if there isn't one already + # https://github.com/jrnl-org/jrnl/issues/768 + # https://github.com/jrnl-org/jrnl/issues/881 + Given we use the config ".yaml" + And we use the password "test" if prompted + When we open the editor and append + """ + [2020-10-29 11:11] First entry. + [2020-10-29 11:11] Second entry. + [2020-10-29 11:13] Third entry. + """ + Then we flush the output + When we run "jrnl -3 --format markdown" + Then the output should be + """ + # 2020 + + ## October + + ### 2020-10-29 11:11 First entry. + + + ### 2020-10-29 11:11 Second entry. + + + ### 2020-10-29 11:13 Third entry. + + """ + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + # | basic_dayone | @todo + + @skip + Scenario Outline: Exporting to XML + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl --export xml" + Then the output should be a valid XML string + And "entries" node in the xml output should have 3 elements + And "tags" in the xml output should contain ["@ipsum", "@tagone", "@tagtwo", "@tagthree"] + And there should be 10 "tag" elements + + Examples: configs + | config | + # | basic_onefile | @todo + # | basic_encrypted | @todo + # | basic_folder | @todo + # | basic_dayone | @todo + + Scenario: Exporting to XML + Given we use the config "tags.yaml" + And we use the password "test" if prompted + When we run "jrnl --export xml" + Then the output should be a valid XML string + And "entries" node in the xml output should have 2 elements + And "tags" in the xml output should contain ["@idea", "@journal", "@dan"] + And there should be 7 "tag" elements + + Scenario Outline: Exporting tags + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl --export tags" + Then the output should be + """ + @tagtwo : 2 + @tagone : 2 + @tagthree : 1 + @ipsum : 1 + """ + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + @todo + Scenario Outline: Exporting fancy + # Needs better emoji support + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl --export fancy" + Then the output should be + """ + ┎──────────────────────────────────────────────────────────────╮2020-08-29 11:11 + ┃ Entry the first. ╘═══════════════╕ + ┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ + ┃ Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada │ + ┃ quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus │ + ┃ pellentesque │ + ┃ augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu │ + ┃ consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In │ + ┃ commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget │ + ┃ venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. │ + ┃ │ + ┃ Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo │ + ┃ ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. │ + ┃ Suspendisse │ + ┃ potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas │ + ┃ eget │ + ┃ molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed │ + ┃ lectus │ + ┃ hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis │ + ┃ feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, │ + ┃ vestibulum │ + ┃ urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod │ + ┃ enim. │ + ┃ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget │ + ┃ velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac │ + ┃ porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per │ + ┃ conubia nostra, per inceptos himenaeos. │ + ┖──────────────────────────────────────────────────────────────────────────────┘ + ┎──────────────────────────────────────────────────────────────╮2020-08-31 14:32 + ┃ A second entry in what I hope to be a long series. ╘═══════════════╕ + ┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ + ┃ Sed sit amet metus et sapien feugiat elementum. Aliquam bibendum lobortis │ + ┃ leo │ + ┃ vitae tempus. Donec eleifend nec mi non volutpat. Lorem ipsum dolor sit │ + ┃ amet, │ + ┃ consectetur adipiscing elit. Praesent ut sodales libero. Maecenas nisl │ + ┃ lorem, │ + ┃ vestibulum in tempus sit amet, fermentum ut arcu. Donec vel vestibulum │ + ┃ lectus, │ + ┃ eget pretium enim. Maecenas diam nunc, imperdiet vitae pharetra sed, pretium │ + ┃ id │ + ┃ lectus. Donec eu metus et turpis tempor tristique ac non ex. In tellus arcu, │ + ┃ egestas at efficitur et, ultrices vel est. Sed commodo et nibh non │ + ┃ elementum. │ + ┃ Mauris tempus vitae neque vel viverra. @tagtwo all by its lonesome. │ + ┃ │ + ┃ Nulla mattis elementum magna, viverra pretium dui fermentum et. Cras vel │ + ┃ vestibulum odio. Quisque sit amet turpis et urna finibus maximus. Interdum │ + ┃ et │ + ┃ malesuada fames ac ante ipsum primis in faucibus. Fusce porttitor iaculis │ + ┃ sem, │ + ┃ non dictum ipsum varius nec. Nulla eu erat at risus gravida blandit non vel │ + ┃ ante. Nam egestas ipsum leo, eu ultricies ipsum tincidunt vel. Morbi a │ + ┃ commodo │ + ┃ eros. │ + ┃ │ + ┃ Nullam dictum, nisl ac varius tempus, ex tortor fermentum nisl, non │ + ┃ tempus dolor neque a lorem. Suspendisse a faucibus ex, vel ornare tortor. │ + ┃ Maecenas tincidunt id felis quis semper. Pellentesque enim libero, fermentum │ + ┃ quis metus id, rhoncus euismod magna. Nulla finibus velit eu purus bibendum │ + ┃ interdum. Integer id justo dui. Integer eu tellus in turpis bibendum │ + ┃ blandit. │ + ┃ Quisque auctor lacinia consectetur. │ + ┖──────────────────────────────────────────────────────────────────────────────┘ + ┎──────────────────────────────────────────────────────────────╮2020-09-24 09:14 + ┃ The third entry finally after weeks without writing. ╘═══════════════╕ + ┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ + ┃ I'm so excited about emojis. 💯 🎶 💩 │ + ┃ │ + ┃ Donec semper pellentesque iaculis. Nullam cursus et justo sit amet │ + ┃ venenatis. │ + ┃ Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. │ + ┃ Nulla │ + ┃ eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis │ + ┃ dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh │ + ┃ malesuada. │ + ┃ Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis │ + ┃ vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan │ + ┃ justo. │ + ┃ Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at │ + ┃ ante eget fringilla. @tagthree and also @tagone │ + ┖──────────────────────────────────────────────────────────────────────────────┘ + """ + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + @skip_win + Scenario Outline: Export to yaml + Given we use the config ".yaml" + And we use the password "test" if prompted + And we create a cache directory + When we run "jrnl --export yaml -o {cache_dir}" + Then the cache should contain the files + """ + 2020-08-29_entry-the-first.md + 2020-08-31_a-second-entry-in-what-i-hope-to-be-a-long-series.md + 2020-09-24_the-third-entry-finally-after-weeks-without-writing.md + """ + And the content of file "2020-08-29_entry-the-first.md" in the cache should be + """ + --- + title: Entry the first. + date: 2020-08-29 11:11 + starred: False + tags: tagone, ipsum, tagtwo + body: | + Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada + quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque + augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu + consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In + commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget + venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. + + Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo + ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse + potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget + molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus + hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis + feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum + urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget + velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac + porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per + conubia nostra, per inceptos himenaeos. + ... + """ + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + # | basic_dayone | + + @skip_win # @todo YAML exporter does not correctly export emoji on Windows + Scenario Outline: Add a blank line to YAML export if there isn't one already + # https://github.com/jrnl-org/jrnl/issues/768 + # https://github.com/jrnl-org/jrnl/issues/881 + Given we use the config ".yaml" + And we use the password "test" if prompted + And we create a cache directory + When we run "jrnl --export yaml -o {cache_dir}" + Then the cache should contain the files + """ + 2020-08-29_entry-the-first.md + 2020-08-31_a-second-entry-in-what-i-hope-to-be-a-long-series.md + 2020-09-24_the-third-entry-finally-after-weeks-without-writing.md + """ + And the content of file "2020-09-24_the-third-entry-finally-after-weeks-without-writing.md" in the cache should be + """ + --- + title: The third entry finally after weeks without writing. + date: 2020-09-24 09:14 + starred: False + tags: tagone, tagthree + body: | + I'm so excited about emojis. 💯 🎶 💩 + + Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. + Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla + eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis + dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. + Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis + vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. + Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at + ante eget fringilla. @tagthree and also @tagone + ... + """ + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + # | basic_dayone | @todo + + Scenario: Empty DayOne entry bodies should not error + # https://github.com/jrnl-org/jrnl/issues/780 + Given we use the config "bug780.yaml" + When we run "jrnl --short" + Then we should get no error + + Scenario Outline: --short displays the short version of entries (only the title) + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl -on 2020-08-31 --short" + Then the output should be "2020-08-31 14:32 A second entry in what I hope to be a long series." + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario Outline: -s displays the short version of entries (only the title) + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl -on 2020-08-31 -s" + Then the output should be "2020-08-31 14:32 A second entry in what I hope to be a long series." + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario: Markdown Support from config file + Given we use the config "format_md.yaml" + When we run "jrnl -n 1" + Then the output should be + """ + # 2013 + + ## June + + ### 2013-06-10 15:40 Life is good. + + But I'm better. + """ + + Scenario: Text Formatter from config file + Given we use the config "format_text.yaml" + When we run "jrnl -n 1" + Then the output should be + """ + [2013-06-10 15:40] Life is good. + But I'm better. + """ + + Scenario Outline: Exporting entries with Cyrillic characters to directory should not fail + Given we use the config ".yaml" + And we use the password "test" if prompted + And we create a cache directory + When we run "jrnl 2020-11-21: Первая" + When we run "jrnl --format md --file {cache_dir} -on 2020-11-21" + Then the cache should contain the files + """ + 2020-11-21_первая.md + """ + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario Outline: Export date counts + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl 2020-08-31 01:01: Hi." + And we run "jrnl --format dates" + Then the output should be + """ + 2020-08-29, 1 + 2020-08-31, 2 + 2020-09-24, 1 + """ + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | diff --git a/tests/features/import.feature b/tests/features/import.feature new file mode 100644 index 00000000..63b042fc --- /dev/null +++ b/tests/features/import.feature @@ -0,0 +1,93 @@ +Feature: Importing data + + Scenario Outline: --import allows new entry from stdin + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl --import" and pipe "[2020-07-05 15:00] Observe and import." + Then we flush the output + When we run "jrnl -c import" + Then the output should contain "Observe and import" + + Examples: Configs + | config | + | basic_onefile | + | basic_encrypted | + # | basic_folder | @todo + # | basic_dayone | @todo + + Scenario Outline: --import allows new large entry from stdin + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl --import" and pipe + """ + [2020-07-05 15:00] Observe and import. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada quis + est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque augue + et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu consequat. + Aenean ante ex, elementum ut interdum et, mattis eget lacus. In commodo nulla nec + tellus placerat, sed ultricies metus bibendum. Duis eget venenatis erat. In at + dolor dui end of entry. + """ + Then we flush the output + When we run "jrnl -on 2020-07-05" + Then the output should contain "2020-07-05 15:00 Observe and import." + And the output should contain "Lorem ipsum" + And the output should contain "end of entry." + + Examples: Configs + | config | + | basic_onefile | + | basic_encrypted | + # | basic_folder | @todo + # | basic_dayone | @todo + + Scenario Outline: --import allows multiple new entries from stdin + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl --import" and pipe + """ + [2020-07-05 15:00] Observe and import. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. + + [2020-07-05 15:01] Twice as nice. + Sed dignissim sed nisl eu consequat. + """ + Then we flush the output + When we run "jrnl -on 2020-07-05" + Then the output should contain "2020-07-05 15:00 Observe and import." + And the output should contain "Lorem ipsum" + And the output should contain "2020-07-05 15:01 Twice as nice." + And the output should contain "Sed dignissim" + + Examples: Configs + | config | + | basic_onefile | + | basic_encrypted | + # | basic_folder | @todo + # | basic_dayone | @todo + + Scenario: --import allows import new entries from file + Given we use the config "simple.yaml" + Then the journal should contain "My first entry." + And the journal should contain "Life is good." + But the journal should not contain "I have an @idea" + And the journal should not contain "I met with" + When we run "jrnl --import --file features/journals/tags.journal" + Then the journal should contain "My first entry." + And the journal should contain "Life is good." + And the journal should contain "PROFIT!" + + Scenario: --import prioritizes --file over pipe data if both are given + Given we use the config "simple.yaml" + Then the journal should contain "My first entry." + And the journal should contain "Life is good." + But the journal should not contain "I have an @idea" + And the journal should not contain "I met with" + When we run "jrnl --import --file features/journals/tags.journal" and pipe + """ + [2020-07-05 15:00] I should not exist! + """ + Then the journal should contain "My first entry." + And the journal should contain "PROFIT!" + But the journal should not contain "I should not exist!" + diff --git a/tests/features/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry b/tests/features/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry new file mode 100644 index 00000000..9721dd55 --- /dev/null +++ b/tests/features/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry @@ -0,0 +1,53 @@ + + + + + Creation Date + 2020-08-29T18:11:00Z + Starred + + Entry Text + Entry the first. +Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada +quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque +augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu +consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In +commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget +venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. + +Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo +ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse +potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget +molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus +hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis +feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum +urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget +velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac +porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per +conubia nostra, per inceptos himenaeos. + Time Zone + America/Los_Angeles + UUID + D04D335AFED711EABA18FAFFC2100C3D + Tags + + ipsum + tagone + tagtwo + + Creator + + Device Agent + + Generation Date + 2020-09-25T02:35:45Z + Host Name + iris.lan + OS Agent + Darwin/19.3.0 + Software Agent + jrnl/v2.4.5 + + + diff --git a/tests/features/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry b/tests/features/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry new file mode 100644 index 00000000..8c2f3c52 --- /dev/null +++ b/tests/features/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry @@ -0,0 +1,55 @@ + + + + + Creation Date + 2020-08-31T21:32:00Z + Starred + + Entry Text + A second entry in what I hope to be a long series. +Sed sit amet metus et sapien feugiat elementum. Aliquam bibendum lobortis leo +vitae tempus. Donec eleifend nec mi non volutpat. Lorem ipsum dolor sit amet, +consectetur adipiscing elit. Praesent ut sodales libero. Maecenas nisl lorem, +vestibulum in tempus sit amet, fermentum ut arcu. Donec vel vestibulum lectus, +eget pretium enim. Maecenas diam nunc, imperdiet vitae pharetra sed, pretium id +lectus. Donec eu metus et turpis tempor tristique ac non ex. In tellus arcu, +egestas at efficitur et, ultrices vel est. Sed commodo et nibh non elementum. +Mauris tempus vitae neque vel viverra. @tagtwo all by its lonesome. + +Nulla mattis elementum magna, viverra pretium dui fermentum et. Cras vel +vestibulum odio. Quisque sit amet turpis et urna finibus maximus. Interdum et +malesuada fames ac ante ipsum primis in faucibus. Fusce porttitor iaculis sem, +non dictum ipsum varius nec. Nulla eu erat at risus gravida blandit non vel +ante. Nam egestas ipsum leo, eu ultricies ipsum tincidunt vel. Morbi a commodo +eros. + +Nullam dictum, nisl ac varius tempus, ex tortor fermentum nisl, non +tempus dolor neque a lorem. Suspendisse a faucibus ex, vel ornare tortor. +Maecenas tincidunt id felis quis semper. Pellentesque enim libero, fermentum +quis metus id, rhoncus euismod magna. Nulla finibus velit eu purus bibendum +interdum. Integer id justo dui. Integer eu tellus in turpis bibendum blandit. +Quisque auctor lacinia consectetur. + Time Zone + America/Los_Angeles + UUID + FC8A86CAFED711EA8892FAFFC2100C3D + Tags + + tagtwo + + Creator + + Device Agent + + Generation Date + 2020-09-25T02:36:59Z + Host Name + iris.lan + OS Agent + Darwin/19.3.0 + Software Agent + jrnl/v2.4.5 + + + diff --git a/tests/features/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry b/tests/features/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry new file mode 100644 index 00000000..d998c36b --- /dev/null +++ b/tests/features/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry @@ -0,0 +1,44 @@ + + + + + Creation Date + 2020-09-24T16:14:00Z + Starred + + Entry Text + The third entry finally after weeks without writing. +I'm so excited about emojis. 💯 🎶 💩 + +Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. +Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla +eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis +dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. +Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis +vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. +Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at +ante eget fringilla. @tagthree and also @tagone + Time Zone + America/Los_Angeles + UUID + FD8ABC8EFED711EABC35FAFFC2100C3D + Tags + + tagthree + tagone + + Creator + + Device Agent + + Generation Date + 2020-09-25T02:37:01Z + Host Name + iris.lan + OS Agent + Darwin/19.3.0 + Software Agent + jrnl/v2.4.5 + + + diff --git a/tests/features/journals/basic_encrypted.journal b/tests/features/journals/basic_encrypted.journal new file mode 100644 index 00000000..ffc122df --- /dev/null +++ b/tests/features/journals/basic_encrypted.journal @@ -0,0 +1 @@ +gAAAAABfb4gQBMqqGn_W8v_s7qCi14bX7inuCOKbsBqIUf7_ch14vTUp7lrysPFvhBp5vGijTwDIbk4LKoIISj8NwM31I8L0zEbMx9y6iyF_zseGGNxBvNN0wzAXa67bs-ohiQhhebcdIc_52sltxL2ELh8JAKUaXRwyapgnMgJ7z6deJppLK-B7RE7BiT0eKjWTDMd2x6cZDswvHs9opDp5yjuKWV5m7x6ggCKYgHT3savT9Tg7V0Fq6K3LGWaE59lCrqlAB0u6dnrDX3qcF4SKyckaniXzRShZGebdkUKDcLFun2V2syZwYQN772xjznIsJ16iXicox2uYKg8CnTefsyCwaOZyBvySGEy3CrlBiuIRIcxCtjKbYJ2B-Aq7LZitnBR7Ny_6_Wm8HsBf3N-cFCp4GShiCKrxuXKcOZ7vszG5EKb78JS85bb0mswU5CSdgp6UAHjIZqfJq00qQsViBCbXq3oklCPZXdQkOf5U0KpG2MVUiD-Zcn5Qj3gnUhSEr-5wKU9tWrE63MGPyE6KjZlArZX2W2LeGnW2CEYw9eREGon06AzLJ4mj3BgtjVWLIdGcCwORXvHRjUqazWgbEmXNVTbtp_cKnkW-rFzRBrUoVme9v-1Y3sH0VvHBq7QIj915VzBklzWs1qzIyTPZG5Db9LvdQ7SiV8slf1Jo7l-ayUUdVj6igvKZcgfB4RUHolJoMps5p4lZ5sPqv59KtSa8DCpuoRczIj71OCpuRVARZgy1m5sUD9xSMxOBdy46u1Jnry6iMtzXWI3mEZe5m7UhmW_L4Zcv4bbk8XjkBeHjPdgm2B69jkLmCBFecD5ztoGesCGt_pNo_sWSKqLHV1-coKFB2Nn__a4utU9NJNdeNRkr8_ahU6tn3jmaFjfQ7cKfrXG_NCcYBRX9fja8EQIeBEp_3TCoXQqhuV_bGsNPA2qL63Pt6YiRaUf1g9FNBqJRlKCSOYNixSXQZN_rTePzx0SQ0aIQhADWls62WX-LG5-byJcB6W2P_cH21hDOXkoNEIyLnCz9HQ6Yd6Fbv7298ps3F6jiUDdWES23zv8sDgBuKUN94qSN34j6MDYGFnGI9zsJ-Y-I2frdlLfWPx3pUL7afcKh1nRgXdjctsTSxU2BDrsu03eBz2IoZjoOR0U51IrNMOD1NNT3kctXxHLuOHSEkwAzS3doncQbdRLi5Gc1dQuOUa4sC-p8gVjUKXO-oi_49kp9Km2Ay9wFg0epBbXx2QMzyMsN2dXeSbHF-BDXD6sULaq5syC0fOHqaMLycTCMk2wLfNyXgEt05WvAiDn-LDsRdylMRW2hXp5HWq3Poaul-7VNg6UEMlwVfgJ-7hNreuO6IRtwmx6YdqMscw0ms6mU_MQZU_dTIPg3JU4KL0YyMqPBPSGNCx3gMp41O05Ubir45FoJSnT5Dkj4v3N0S87Ys3HuFLverASsGt9bkcSzd2uMKCJjkspemPPi9VhrY4IOO03DWSWbHmxYzFc1SJ-24WM8Ch404QKpe1qy5LNzFgLvDwQhSIHjluezHXqrD-DVh1lWNNY3WmHI2ubOZfaorvLKqzBPZ6AhpIa60rKjm0OZIQOmJwWXwkdnzut6m8PtoiLzRN897YMgeztf1nmDwp0xE-EhknVZ3WV3TeqgZJ5ykfHQ5BU8x0Db57-UtKSuesKbqPPdBe91OdsPpkGlyl6psHj1_gPm4nLvzXQePwiPaEemR_gYCWGPvl9l1ANJufgCV9qQTmZGof3fb9mjv-9lS-9l_m8KirPPRpSBToNeDtk50ceYUsOlDGzIyusppG9pOcIGyiln1IO5aZ8d4_1E83qjcHTSaKGizICZU7a-pt5STBPMesy3JgBm23A2jO4m68ayBRMcLnw_RirHvvBaj0C6UR2tac45F0Ob3PpXcvFuK0g54ziIAhzGqwF9I-LZ6asXQWMW4y4EBOak8JJBorkfztzfkMaIgGu-4ZoRKOkVfdr4uzcghk3r6KUxD4-nv1ioX69-G5RwhMHppYk7z8RXS1cq5FkvzXbfEQ-Uv6M-sx32DcUy9dH-ZYhc7UWm75JJfiNXLaXT_bsc6VqQ7KPkg2-RA7CywUFCW9S0S-XdO03VdwqlUVo7fp1SKywEfhZv_9bhDCdMJBwZmigv2KP9Iz7fF6LrpLwZkzHuQGFPcyTHFpsVIFrFyJjNYCXpET9y0Q5Vt4fnea5fy-9ZiCt3S8aS0YOFJ35_kM5i3ss8eFPL0v7fIQS3ZilzdGB3bWL0J7kppHN_ekHu-wVk3UZxauoFh7hXLjPcipua-FYUIklLjcK6DG1bYP7_q6OnkC8Jl650FNezeWPomHEv7l_DO3y0tjI6SGdWvL3ZJns7Xp3ew8KsCREAUO7ffqumD03uF9N-9uWbDDjM7rk0vcg0ggfOs9Ni725mxqYpu4R285XCOVWHDvw7iU6eAvE6ry8TDXQBbNgGjTuTYFYYli7GuOqMxFIe1op2s7sRnoJE8O0J76S6APhjhjcnZRSuONWkVG_5o83uFMPSF8DtqLwuRA5E8AGfIwAUcj324sw-DA0ixBGUqomb-osUIisv3x0b044xn-FvD-8R3PZDnPbPsao8XYNxfQWStrNcZSrX2Ua-WAcv9qbQ73_57RKW4pao4ajOu7K5800D231WGiIa6aJzDnFUlzXEzYxFQyx7qegkm_9rrEp_v8TC9mfAcjWX5DMrCkxUskx9YKDfpFYq4NuxO_414gReKzd-lmorfigvttgS10N1XD74SwFluXJv-bqTbI5-SuYAhDGMv1dqrn38i3rOMQqqnQomvaUJRprqxUsKz14sSE1Y-cNqq1FXzZ6vIJq-K3YTfFWPRLeqi6gHzqS_R2YBXXUduKuYgmakiVdP3bWc-Ca8WKh5sVi6P51MO-cS7i9AZWOaOz7F8PsB4JZxAJjSOr3NBmv3EEve9auTFCudRjfC6668I_NMHaTP5CCV4cuhuAxUuKUGgd6WFjDcvoYPyn_lu3bQiqD9MEag4CaJYI9PlraRv5mbqptwxv3pca7usd0GmXN_2No_nwxB4gVb48LsBBkH35njCa5iv2EKXUSOf0k3swaTSEahqbyI4EDzPXtU5uBO39iQzNpgfV_sUpnGdysjqueUVcdWGI_s5CnrNJ-_yDAY06AoXfLrjP8_3NXB2058xZ2rfmTNJNCULz9634dICJReXNnmplxIg3i6GbzFvjfNtqjrWr_iqBShyIwuOUJRbXzdJNggx2BDNG-PEWDXl89SaudFICkDvyZKEcATIss6ZXfULIMfCrqmWmFwgXfNEd9TuvjqoxFlLSaY4UfDMiYa_arUMblFfoo5nV07GANhUoQd-6HRe7LjYeX5VRodOx6ZmZjIAUq-DYr-hatJJFR2tjT_qZht2MJeYT3GZ3o54m8zBBt0JTN7HVpKaOaM3A2hEM_Ah0QZ-DkLDxtCzMuv987GDiLT2-Riya97a47yHIJhZFzFpflW2FcuC8RFWXlfUKTQfZkFmxh3MUekUuS4yu4Z121xojVswk_4P7-FqLaSnGT2epI69I_cvalRx3wjds9-5TFYqf4GridlFBRx6Fv2fpNB9Zvp9k7NQ9oYcPuXGLoXH5kmWBagPhEGKHA_pjFUZmCuwUIoeP4nP8lhFrX8OGezsbSBG773CRJzEdfcgAc5G-p6M_24WZLZHDrsVBAvgrNt6R9eQbEviWU28t_417QCp-or9qqt4OTKv1dp_4MlZh8YBg2-dtpvzSc1l5e4kQFJu7oWlpbgsjB6pl1oRRKp1maedX-gOAf559zC4l85gfEpPln9Cnl6xvERQzfO0Ey4q91SdsgK7i7FBrKKmi2wGiemFvnaQsrjZ_IFujLo8-2c8g9zTiyH1knyoVOAAnQxqGpsz6z6PNfSxr3_G8tOlNFTV-yqN_LdVHMgXtXjn3U9koGsfMulyUcBDdR3d_0Yn6iEjBt77tbxKi2ry-0gQrB1fdGsgKjyE_tMrW8D_lQz0IXsVOzd2ixsFVXMFzD6OOD8JldV0FbA-VDAS-Tp_ezIZVp6lRq54XBgvsjzDyOmOgDbSOQN6SQmvxPnIsml1wgmtm80z-9gHBqmimHBtLKB6L7CtLmmPICMS2pX3eWOmakxscxqs8AVjijJdz_NYNfcdBeDj_fhm6dqD6iwk3EBZZfsrmMGdXtAMqf1r9ng9tsz-FriXwQiJ3IM3loBsk5DKr9CcaJtKSPuwDDlRynD2vwcD-XyF6YTQdSJa9fEcq-qXya2Scj4mqQ4RDemJgErdradRfwJfII3fWHh18XxmYVqi9Bwn3YRgwEadyo0-HjbNq6vJXi12igmP99ciRAfMVQLjfUfTwoOHj44Y2Ru_hPjJcvB6FIn6KLrrCSrZnrshFdFn4L36z1CrS8fbtdvrG3kdZQxsUJnMqttuwKRpLnDWTWkIwj_GRBFrzCFgbwGp1XYhemxggyKVuhZPfyyTIM9rhlPth6eGyrpYfap24Av_mGPRBLnzcjtpGbACGdKQL034kVmI7yENGvmY40KSrWsVG_BE9bSJhx0EptFsT2IxnxbuFD4hGb4fFag9V0BDiKpUoOZqIVqVO8cAp-5w4twvWZKkrhu16JNlLoXWMoFANrw-tp5LKSin1CUeRa4LWVI1GR8tRkIad_GnCHRv9JEMswlNy9wi2sDNsSxWT7WNasUW5-glgK9pR7d2pXGGOWfHj1U6CKIqmAiO3iw8igzhvyx_dAxMxPo \ No newline at end of file diff --git a/tests/features/journals/basic_folder/2020/08/29.txt b/tests/features/journals/basic_folder/2020/08/29.txt new file mode 100644 index 00000000..c8af54ca --- /dev/null +++ b/tests/features/journals/basic_folder/2020/08/29.txt @@ -0,0 +1,19 @@ +[2020-08-29 11:11:00 AM] Entry the first. +Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada +quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque +augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu +consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In +commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget +venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. + +Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo +ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse +potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget +molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus +hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis +feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum +urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget +velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac +porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per +conubia nostra, per inceptos himenaeos. diff --git a/tests/features/journals/basic_folder/2020/08/31.txt b/tests/features/journals/basic_folder/2020/08/31.txt new file mode 100644 index 00000000..826e7cdb --- /dev/null +++ b/tests/features/journals/basic_folder/2020/08/31.txt @@ -0,0 +1,23 @@ +[2020-08-31 02:32:00 PM] A second entry in what I hope to be a long series. * +Sed sit amet metus et sapien feugiat elementum. Aliquam bibendum lobortis leo +vitae tempus. Donec eleifend nec mi non volutpat. Lorem ipsum dolor sit amet, +consectetur adipiscing elit. Praesent ut sodales libero. Maecenas nisl lorem, +vestibulum in tempus sit amet, fermentum ut arcu. Donec vel vestibulum lectus, +eget pretium enim. Maecenas diam nunc, imperdiet vitae pharetra sed, pretium id +lectus. Donec eu metus et turpis tempor tristique ac non ex. In tellus arcu, +egestas at efficitur et, ultrices vel est. Sed commodo et nibh non elementum. +Mauris tempus vitae neque vel viverra. @tagtwo all by its lonesome. + +Nulla mattis elementum magna, viverra pretium dui fermentum et. Cras vel +vestibulum odio. Quisque sit amet turpis et urna finibus maximus. Interdum et +malesuada fames ac ante ipsum primis in faucibus. Fusce porttitor iaculis sem, +non dictum ipsum varius nec. Nulla eu erat at risus gravida blandit non vel +ante. Nam egestas ipsum leo, eu ultricies ipsum tincidunt vel. Morbi a commodo +eros. + +Nullam dictum, nisl ac varius tempus, ex tortor fermentum nisl, non +tempus dolor neque a lorem. Suspendisse a faucibus ex, vel ornare tortor. +Maecenas tincidunt id felis quis semper. Pellentesque enim libero, fermentum +quis metus id, rhoncus euismod magna. Nulla finibus velit eu purus bibendum +interdum. Integer id justo dui. Integer eu tellus in turpis bibendum blandit. +Quisque auctor lacinia consectetur. diff --git a/tests/features/journals/basic_folder/2020/09/24.txt b/tests/features/journals/basic_folder/2020/09/24.txt new file mode 100644 index 00000000..2bd885ce --- /dev/null +++ b/tests/features/journals/basic_folder/2020/09/24.txt @@ -0,0 +1,11 @@ +[2020-09-24 09:14:00 AM] The third entry finally after weeks without writing. +I'm so excited about emojis. 💯 🎶 💩 + +Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. +Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla +eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis +dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. +Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis +vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. +Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at +ante eget fringilla. @tagthree and also @tagone diff --git a/tests/features/journals/basic_onefile.journal b/tests/features/journals/basic_onefile.journal new file mode 100644 index 00000000..0d988049 --- /dev/null +++ b/tests/features/journals/basic_onefile.journal @@ -0,0 +1,58 @@ +[2020-08-29 11:11] Entry the first. + +Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada +quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque +augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu +consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In +commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget +venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. + +Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo +ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse +potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget +molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus +hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis +feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum +urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget +velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac +porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per +conubia nostra, per inceptos himenaeos. + +[2020-08-31 14:32] A second entry in what I hope to be a long series. * + +Sed sit amet metus et sapien feugiat elementum. Aliquam bibendum lobortis leo +vitae tempus. Donec eleifend nec mi non volutpat. Lorem ipsum dolor sit amet, +consectetur adipiscing elit. Praesent ut sodales libero. Maecenas nisl lorem, +vestibulum in tempus sit amet, fermentum ut arcu. Donec vel vestibulum lectus, +eget pretium enim. Maecenas diam nunc, imperdiet vitae pharetra sed, pretium id +lectus. Donec eu metus et turpis tempor tristique ac non ex. In tellus arcu, +egestas at efficitur et, ultrices vel est. Sed commodo et nibh non elementum. +Mauris tempus vitae neque vel viverra. @tagtwo all by its lonesome. + +Nulla mattis elementum magna, viverra pretium dui fermentum et. Cras vel +vestibulum odio. Quisque sit amet turpis et urna finibus maximus. Interdum et +malesuada fames ac ante ipsum primis in faucibus. Fusce porttitor iaculis sem, +non dictum ipsum varius nec. Nulla eu erat at risus gravida blandit non vel +ante. Nam egestas ipsum leo, eu ultricies ipsum tincidunt vel. Morbi a commodo +eros. + +Nullam dictum, nisl ac varius tempus, ex tortor fermentum nisl, non +tempus dolor neque a lorem. Suspendisse a faucibus ex, vel ornare tortor. +Maecenas tincidunt id felis quis semper. Pellentesque enim libero, fermentum +quis metus id, rhoncus euismod magna. Nulla finibus velit eu purus bibendum +interdum. Integer id justo dui. Integer eu tellus in turpis bibendum blandit. +Quisque auctor lacinia consectetur. + +[2020-09-24 09:14] The third entry finally after weeks without writing. + +I'm so excited about emojis. 💯 🎶 💩 + +Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. +Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla +eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis +dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. +Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis +vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. +Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at +ante eget fringilla. @tagthree and also @tagone diff --git a/tests/features/journals/brackets.journal b/tests/features/journals/brackets.journal new file mode 100644 index 00000000..4649ea3e --- /dev/null +++ b/tests/features/journals/brackets.journal @@ -0,0 +1,2 @@ +[2019-07-08 05:42] Entry subject +[1] line starting with 1 diff --git a/tests/features/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry b/tests/features/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry new file mode 100644 index 00000000..066821bb --- /dev/null +++ b/tests/features/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry @@ -0,0 +1,56 @@ + + + + + Creation Date + 2013-10-27T02:27:27Z + Creator + + Device Agent + iPhone/iPhone3,1 + Generation Date + 2013-10-27T07:02:27Z + Host Name + omrt104001 + OS Agent + iOS/7.0.3 + Software Agent + Day One (iOS)/1.11.4 + + Entry Text + Some text. + Location + + Administrative Area + Östergötlands län + Country + Sverige + Latitude + 58.383400000000000 + Locality + City + Longitude + 15.577170000000000 + Place Name + Street + + Starred + + Time Zone + Europe/Stockholm + UUID + B40EE704E15846DE8D45C44118A4D511 + Weather + + Celsius + 12 + Description + Clear + Fahrenheit + 54 + IconName + sunnyn.png + + + diff --git a/tests/features/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry b/tests/features/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry new file mode 100644 index 00000000..ea3efec5 --- /dev/null +++ b/tests/features/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry @@ -0,0 +1,52 @@ + + Creation Date + 2013-10-27T02:27:27Z + Creator + + Device Agent + iPhone/iPhone3,1 + Generation Date + 2013-10-27T07:02:27Z + Host Name + omrt104001 + OS Agent + iOS/7.0.3 + Software Agent + Day One (iOS)/1.11.4 + + Entry Text + This is not a valid plist. + Location + + Administrative Area + Östergötlands län + Country + Sverige + Latitude + 58.383400000000000 + Locality + City + Longitude + 15.577170000000000 + Place Name + Street + + Starred + + Time Zone + Europe/Stockholm + UUID + B40EE704E15846DE8D45C44118A4D511 + Weather + + Celsius + 12 + Description + Clear + Fahrenheit + 54 + IconName + sunnyn.png + + + diff --git a/tests/features/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry b/tests/features/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry new file mode 100644 index 00000000..426f1ea8 --- /dev/null +++ b/tests/features/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry @@ -0,0 +1,33 @@ + + + + + Activity + Stationary + Creation Date + 2019-12-30T21:28:54Z + Entry Text + + Starred + + UUID + 48A25033B34047C591160A4480197D8B + Creator + + Device Agent + PC + Generation Date + 2019-12-30T21:28:54Z + Host Name + LE-TREPORT + OS Agent + Microsoft Windows/10 Home + Software Agent + Journaley/2.1 + + Tags + + i_have_no_body + + + diff --git a/tests/features/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry b/tests/features/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry new file mode 100644 index 00000000..1ac26242 --- /dev/null +++ b/tests/features/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry @@ -0,0 +1,34 @@ + + + + + Creation Date + 2013-05-17T18:39:20Z + Creator + + Device Agent + Macintosh/MacBookAir5,2 + Generation Date + 2013-08-17T18:39:20Z + Host Name + Egeria + OS Agent + Mac OS X/10.8.4 + Software Agent + Day One (Mac)/1.8 + + Entry Text + This entry has tags! + Starred + + Tags + + work + PLaY + + Time Zone + America/Los_Angeles + UUID + 044F3747A38546168B572C2E3F217FA2 + + diff --git a/tests/features/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry b/tests/features/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry new file mode 100644 index 00000000..927de884 --- /dev/null +++ b/tests/features/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry @@ -0,0 +1,46 @@ + + + + + Creation Date + 2013-06-17T18:38:29Z + Creator + + Device Agent + Macintosh/MacBookAir5,2 + Generation Date + 2013-08-17T18:38:29Z + Host Name + Egeria + OS Agent + Mac OS X/10.8.4 + Software Agent + Day One (Mac)/1.8 + + Entry Text + This entry has a location. + Location + + Administrative Area + California + Country + Germany + Latitude + 52.4979764 + Locality + Berlin + Longitude + 13.2404758 + Place Name + Abandoned Spy Tower + + Starred + + Tags + + Time Zone + Europe/Berlin + UUID + 0BDDD6CDA43C4A9AA2681517CC35AD9D + + diff --git a/tests/features/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry b/tests/features/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry new file mode 100644 index 00000000..16260763 --- /dev/null +++ b/tests/features/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry @@ -0,0 +1,31 @@ + + + + + Creation Date + 2013-07-17T18:38:08Z + Creator + + Device Agent + Macintosh/MacBookAir5,2 + Generation Date + 2013-08-17T18:38:08Z + Host Name + Egeria + OS Agent + Mac OS X/10.8.4 + Software Agent + Day One (Mac)/1.8 + + Entry Text + This entry is starred! + Starred + + Tags + + Time Zone + America/Los_Angeles + UUID + 422BC895507944A291E6FC44FC6B8BFC + + diff --git a/tests/features/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry b/tests/features/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry new file mode 100644 index 00000000..9ebaf538 --- /dev/null +++ b/tests/features/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry @@ -0,0 +1,29 @@ + + + + + Creation Date + 2013-01-17T18:37:50Z + Creator + + Device Agent + Macintosh/MacBookAir5,2 + Generation Date + 2013-08-17T18:37:50Z + Host Name + Egeria + OS Agent + Mac OS X/10.8.4 + Software Agent + Day One (Mac)/1.8 + + Entry Text + This is a DayOne entry without Timezone. + Starred + + Tags + + UUID + 4BB1F46946AD439996C9B59DE7C4DDC1 + + diff --git a/tests/features/journals/dayone_empty.dayone/entries/empty.txt b/tests/features/journals/dayone_empty.dayone/entries/empty.txt new file mode 100644 index 00000000..c86b8f66 --- /dev/null +++ b/tests/features/journals/dayone_empty.dayone/entries/empty.txt @@ -0,0 +1 @@ +This file exists to preserve the directory structure, but should be ignored by jrnl. diff --git a/tests/features/journals/deletion.journal b/tests/features/journals/deletion.journal new file mode 100644 index 00000000..c0fa689d --- /dev/null +++ b/tests/features/journals/deletion.journal @@ -0,0 +1,5 @@ +[2019-10-29 11:11] First entry. + +[2019-10-29 11:11] Second entry. + +[2019-10-29 11:13] Third entry. \ No newline at end of file diff --git a/tests/features/journals/deletion_filters.journal b/tests/features/journals/deletion_filters.journal new file mode 100644 index 00000000..9a3747db --- /dev/null +++ b/tests/features/journals/deletion_filters.journal @@ -0,0 +1,14 @@ +[2019-10-01 08:00] It's just another day in October. +Not much to write about. + +[2020-01-01 08:00] Happy New Year! +So this is the New Year. @holidays + +[2020-03-01 08:00] It's just another day in March. +A stick, a stone, it's the end of the road. + +[2020-05-01 09:00] Happy May Day! +@holidays @springtime Several holidays fall on this date. + +[2020-05-02 12:10] Writing tests. * +@springtime They will help prevent bugs. diff --git a/tests/features/journals/empty_folder/empty b/tests/features/journals/empty_folder/empty new file mode 100644 index 00000000..175b82b5 --- /dev/null +++ b/tests/features/journals/empty_folder/empty @@ -0,0 +1 @@ +Nothing to see here diff --git a/tests/features/journals/encrypted.journal b/tests/features/journals/encrypted.journal new file mode 100644 index 00000000..d2a5fcbe --- /dev/null +++ b/tests/features/journals/encrypted.journal @@ -0,0 +1 @@ +gAAAAABVIHB7tnwKExG7aC5ZbAbBL9SG2oY2GENeoOJ22i1PZigOvCYvrQN3kpsu0KGr7ay5K-_46R5YFlqJvtQ8anPH2FSITsaZy-l5Lz_5quw3rmzhLwAR1tc0icgtR4MEpXEdsuQ7cyb12Xq-JLDrnATs0id5Vow9Ri_tE7Xe4BXgXaySn3aRPwWKoninVxVPVvETY3MXHSUEXV9OZ-pH5kYBLGYbLA== diff --git a/tests/features/journals/encrypted_jrnl-1-9-5.journal b/tests/features/journals/encrypted_jrnl-1-9-5.journal new file mode 100644 index 0000000000000000000000000000000000000000..339b47baf9671f4550efeb9b6a0cfcd5032255d6 GIT binary patch literal 128 zcmV-`0Du3(bJIGVsY(mXmoW-2hF&*L`0NbJTYlTUr8*^Qm97}8E^3^1bZ$P^M literal 0 HcmV?d00001 diff --git a/tests/features/journals/little_endian_dates.journal b/tests/features/journals/little_endian_dates.journal new file mode 100644 index 00000000..d7492969 --- /dev/null +++ b/tests/features/journals/little_endian_dates.journal @@ -0,0 +1,5 @@ +[09.06.2013 15:39] My first entry. +Everything is alright + +[10.07.2013 15:40] Life is good. +But I'm better. diff --git a/tests/features/journals/markdown-headings-335.journal b/tests/features/journals/markdown-headings-335.journal new file mode 100644 index 00000000..30f592ef --- /dev/null +++ b/tests/features/journals/markdown-headings-335.journal @@ -0,0 +1,42 @@ +[2015-04-14 13:23] Heading Test + +H1-1 += + +H1-2 +=== + +H1-3 +============================ + +H2-1 +- + +H2-2 +--- + +H2-3 +---------------------------------- + +Horizontal Rules (ignore) + +--- + +=== + +# ATX H1 + +## ATX H2 + +### ATX H3 + +#### ATX H4 + +##### ATX H5 + +###### ATX H6 + +Stuff + +More stuff +more stuff again diff --git a/tests/features/journals/mostlyreadabledates.journal b/tests/features/journals/mostlyreadabledates.journal new file mode 100644 index 00000000..bd211bf5 --- /dev/null +++ b/tests/features/journals/mostlyreadabledates.journal @@ -0,0 +1,8 @@ +[2019-07-18 14:23] Entry subject +Time machines are possible. I know, because I've built one in my garage. + +[2019-07-19 14:23] Entry subject +I'm going to activate the machine. Nobody knows what comes next after this. Or before this? + +[2019-07 14:23] Entry subject +I've crossed so many timelines. Is there any going back? diff --git a/tests/features/journals/multiline-tags.journal b/tests/features/journals/multiline-tags.journal new file mode 100644 index 00000000..1fb8706f --- /dev/null +++ b/tests/features/journals/multiline-tags.journal @@ -0,0 +1,7 @@ +[2013-06-09 15:39] Multiple @line entry with @tags. +Tag with @punctuation. afterwards +@TagOnLineAloneWithOutPunctuation +@TagOnLineAloneWithPunctuation. +Text before @tag. And After. +@hi. Hello +hi Hello \ No newline at end of file diff --git a/tests/features/journals/multiline.journal b/tests/features/journals/multiline.journal new file mode 100644 index 00000000..294ed141 --- /dev/null +++ b/tests/features/journals/multiline.journal @@ -0,0 +1,5 @@ +[2013-06-09 15:39] Multiple line entry. +This is the first line. +This line doesn't have any ending punctuation + +There is a blank line above this. diff --git a/tests/features/journals/simple.journal b/tests/features/journals/simple.journal new file mode 100644 index 00000000..8336068e --- /dev/null +++ b/tests/features/journals/simple.journal @@ -0,0 +1,5 @@ +[2013-06-09 15:39] My first entry. +Everything is alright + +[2013-06-10 15:40] Life is good. +But I'm better. diff --git a/tests/features/journals/simple_jrnl-1-9-5.journal b/tests/features/journals/simple_jrnl-1-9-5.journal new file mode 100644 index 00000000..7bb6c5ac --- /dev/null +++ b/tests/features/journals/simple_jrnl-1-9-5.journal @@ -0,0 +1,13 @@ +2010-06-10 15:00 A life without chocolate is like a bad analogy. + +2013-06-10 15:40 He said "[this] is the best time to be alive". +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada +quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque +augue et venenatis facilisis. + +[2019-08-03 12:55] Some chat log or something + +Suspendisse potenti. Sed dignissim sed nisl eu consequat. Aenean ante ex, +elementum ut interdum et, mattis eget lacus. In commodo nulla nec tellus +placerat, sed ultricies metus bibendum. Duis eget venenatis erat. In at dolor +dui. diff --git a/tests/features/journals/simple_jrnl-1-9-5_little_endian_dates.journal b/tests/features/journals/simple_jrnl-1-9-5_little_endian_dates.journal new file mode 100644 index 00000000..328b23f4 --- /dev/null +++ b/tests/features/journals/simple_jrnl-1-9-5_little_endian_dates.journal @@ -0,0 +1,13 @@ +10.06.2010 15:00 A life without chocolate is like a bad analogy. + +10.06.2013 15:40 He said "[this] is the best time to be alive". +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada +quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque +augue et venenatis facilisis. + +[03.08.2019 12:55] Some chat log or something + +Suspendisse potenti. Sed dignissim sed nisl eu consequat. Aenean ante ex, +elementum ut interdum et, mattis eget lacus. In commodo nulla nec tellus +placerat, sed ultricies metus bibendum. Duis eget venenatis erat. In at dolor +dui. diff --git a/tests/features/journals/tags-216.journal b/tests/features/journals/tags-216.journal new file mode 100644 index 00000000..08b6d630 --- /dev/null +++ b/tests/features/journals/tags-216.journal @@ -0,0 +1,2 @@ +[2013-06-10 15:40] I programmed for @OS/2. +Almost makes me want to go back to @C++, though. (Still better than @C#). diff --git a/tests/features/journals/tags-237.journal b/tests/features/journals/tags-237.journal new file mode 100644 index 00000000..be050652 --- /dev/null +++ b/tests/features/journals/tags-237.journal @@ -0,0 +1,3 @@ +[2014-07-22 11:11] This entry has an email. +@Newline tag should show as a tag. +Kyla's @email is kyla@clevelandunderdog.org and Guinness's is guinness@fortheloveofpits.org. diff --git a/tests/features/journals/tags.journal b/tests/features/journals/tags.journal new file mode 100644 index 00000000..a28f3159 --- /dev/null +++ b/tests/features/journals/tags.journal @@ -0,0 +1,8 @@ +[2013-04-09 15:39] I have an @idea: +(1) write a command line @journal software +(2) ??? +(3) PROFIT! + +[2013-06-10 15:40] I met with @dan. +As alway's he shared his latest @idea on how to rule the world with me. +inst diff --git a/tests/features/journals/unreadabledates.journal b/tests/features/journals/unreadabledates.journal new file mode 100644 index 00000000..53ef1d60 --- /dev/null +++ b/tests/features/journals/unreadabledates.journal @@ -0,0 +1,5 @@ +[ashasd7zdskhz7asdkjasd] Entry subject +I've lost track of time. + +[sadfhakjsdf88sdf7sdff] Entry subject +Time has no meaning. diff --git a/tests/features/journals/work.journal b/tests/features/journals/work.journal new file mode 100644 index 00000000..e69de29b diff --git a/tests/features/multiple_journals.feature b/tests/features/multiple_journals.feature new file mode 100644 index 00000000..222be100 --- /dev/null +++ b/tests/features/multiple_journals.feature @@ -0,0 +1,65 @@ +Feature: Multiple journals + + Scenario: Loading a config with two journals + Given we use the config "multiple.yaml" + Then journal "default" should have 2 entries + And journal "work" should have 0 entries + + Scenario: Write to default config by default + Given we use the config "multiple.yaml" + When we run "jrnl this goes to default" + Then journal "default" should have 3 entries + And journal "work" should have 0 entries + + Scenario: Write to specified journal + Given we use the config "multiple.yaml" + When we run "jrnl work a long day in the office" + Then journal "default" should have 2 entries + And journal "work" should have 1 entry + + Scenario: Tell user which journal was used + Given we use the config "multiple.yaml" + When we run "jrnl work a long day in the office" + Then we should see the message "Entry added to work journal" + + Scenario: Write to specified journal with a timestamp + Given we use the config "multiple.yaml" + When we run "jrnl work 23 july 2012: a long day in the office" + Then journal "default" should have 2 entries + And journal "work" should have 1 entry + And journal "work" should contain "2012-07-23" + + Scenario: Write to specified journal without a timestamp but with colon + Given we use the config "multiple.yaml" + When we run "jrnl work : a long day in the office" + Then journal "default" should have 2 entries + And journal "work" should have 1 entry + And journal "work" should contain "a long day in the office" + + Scenario: Write to specified journal without a timestamp but with colon + Given we use the config "multiple.yaml" + When we run "jrnl work: a long day in the office" + Then journal "default" should have 2 entries + And journal "work" should have 1 entry + And journal "work" should contain "a long day in the office" + + Scenario: Create new journals as required + Given we use the config "multiple.yaml" + Then journal "ideas" should not exist + When we run "jrnl ideas 23 july 2012: sell my junk on ebay and make lots of money" + Then journal "ideas" should have 1 entry + + Scenario: Don't crash if no default journal is specified + Given we use the config "bug343.yaml" + When we run "jrnl a long day in the office" + Then we should see the message "No default journal configured" + + Scenario: Don't crash if no file exists for a configured encrypted journal + Given we use the config "multiple.yaml" + When we run "jrnl new_encrypted Adding first entry" and enter + """ + these three eyes + these three eyes + n + """ + Then we should see the message "Encrypted journal 'new_encrypted' created" diff --git a/tests/features/password.feature b/tests/features/password.feature new file mode 100644 index 00000000..332ba86e --- /dev/null +++ b/tests/features/password.feature @@ -0,0 +1,116 @@ +Feature: Using the installed keyring + + Scenario: Storing a password in keyring + Given we use the config "multiple.yaml" + And we have a keyring + When we run "jrnl simple --encrypt" and enter + """ + sabertooth + sabertooth + y + """ + Then the config for journal "simple" should have "encrypt" set to "bool:True" + When we run "jrnl simple -n 1" + Then the output should contain "2013-06-10 15:40 Life is good" + + Scenario: Encrypt journal with no keyring backend and do not store in keyring + Given we use the config "simple.yaml" + And we do not have a keyring + When we run "jrnl test entry" + And we run "jrnl --encrypt" and enter + """ + password + password + n + """ + Then we should get no error + And we should not see the message "Failed to retrieve keyring" + + Scenario: Encrypt journal with no keyring backend and do store in keyring + Given we use the config "simple.yaml" + And we do not have a keyring + When we run "jrnl test entry" + And we run "jrnl --encrypt" and enter + """ + password + password + y + """ + Then we should get no error + And we should not see the message "Failed to retrieve keyring" + # @todo add step to check contents of keyring + + @todo + Scenario: Open an encrypted journal with wrong password in keyring + # This should ask the user for the password after the keyring fails + + @todo + Scenario: Decrypt journal with password in keyring + + @todo + Scenario: Decrypt journal without a keyring + + Scenario: Encrypt journal when keyring exists but fails + Given we use the config "simple.yaml" + And we have a failed keyring + When we run "jrnl --encrypt" and enter + """ + this password will not be saved in keyring + this password will not be saved in keyring + y + """ + Then we should see the message "Failed to retrieve keyring" + And we should get no error + And we should be prompted for a password + And the config for journal "default" should have "encrypt" set to "bool:True" + + Scenario: Decrypt journal when keyring exists but fails + Given we use the config "encrypted.yaml" + And we have a failed keyring + When we run "jrnl --decrypt" and enter "bad doggie no biscuit" + Then we should see the message "Failed to retrieve keyring" + And we should get no error + And we should be prompted for a password + And we should see the message "Journal decrypted" + And the config for journal "default" should have "encrypt" set to "bool:False" + And the journal should have 2 entries + + Scenario: Open encrypted journal when keyring exists but fails + # This should ask the user for the password after the keyring fails + Given we use the config "encrypted.yaml" + And we have a failed keyring + When we run "jrnl -n 1" and enter "bad doggie no biscuit" + Then we should see the message "Failed to retrieve keyring" + And we should get no error + And we should be prompted for a password + And the output should contain "2013-06-10 15:40 Life is good" + + Scenario: Mistyping your password + Given we use the config "simple.yaml" + When we run "jrnl --encrypt" and enter + """ + swordfish + sordfish + """ + Then we should be prompted for a password + And we should see the message "Passwords did not match" + And the config for journal "default" should not have "encrypt" set + And the journal should have 2 entries + + Scenario: Mistyping your password, then getting it right + Given we use the config "simple.yaml" + When we run "jrnl --encrypt" and enter + """ + swordfish + sordfish + swordfish + swordfish + n + """ + Then we should be prompted for a password + And we should see the message "Passwords did not match" + And we should see the message "Journal encrypted" + And the config for journal "default" should have "encrypt" set to "bool: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" diff --git a/tests/features/search.feature b/tests/features/search.feature new file mode 100644 index 00000000..22351b7e --- /dev/null +++ b/tests/features/search.feature @@ -0,0 +1,318 @@ +Feature: Searching in a journal + + Scenario Outline: Displaying entries using -on today should display entries created today + Given we use the config ".yaml" + When we run "jrnl today: Adding an entry right now." + Then we should see the message "Entry added" + When we run "jrnl -on today" + Then the output should contain "Adding an entry right now." + But the output should not contain "Everything is alright" + And the output should not contain "Life is good" + + Examples: configs + | config | + | simple | + | empty_folder | + | dayone | + + Scenario Outline: Displaying entries using -from day should display correct entries + Given we use the config ".yaml" + When we run "jrnl yesterday: This thing happened yesterday" + Then we should see the message "Entry added" + When we run "jrnl today at 11:59pm: Adding an entry right now." + Then we should see the message "Entry added" + When we run "jrnl tomorrow: A future entry." + Then we should see the message "Entry added" + When we run "jrnl -from today" + Then the output should contain "Adding an entry right now." + And the output should contain "A future entry." + And the output should not contain "This thing happened yesterday" + + Examples: configs + | config | + | simple | + | empty_folder | + | dayone | + + Scenario Outline: Displaying entries using -from and -to day should display correct entries + Given we use the config ".yaml" + When we run "jrnl yesterday: This thing happened yesterday" + Then we should see the message "Entry added" + When we run "jrnl today at 11:59pm: Adding an entry right now." + Then we should see the message "Entry added" + When we run "jrnl tomorrow: A future entry." + Then we should see the message "Entry added" + When we run "jrnl -from yesterday -to today" + Then the output should contain "This thing happened yesterday" + And the output should contain "Adding an entry right now." + And the output should not contain "A future entry." + + Examples: configs + | config | + | simple | + | empty_folder | + | dayone | + + Scenario Outline: Searching for a string + Given we use the config ".yaml" + When we run "jrnl -contains first --short" + Then we should get no error + And the output should be + """ + 2020-08-29 11:11 Entry the first. + """ + + Examples: configs + | config | + | basic_onefile | + | basic_folder | + | basic_dayone | + + Scenario Outline: Searching for a string within tag results + Given we use the config ".yaml" + When we run "jrnl @tagone -contains maybe" + Then we should get no error + And the output should contain "maybe" + + Examples: configs + | config | + | basic_onefile | + | basic_folder | + | basic_dayone | + + Scenario Outline: Searching for a string within AND tag results + Given we use the config ".yaml" + When we run "jrnl -and @tagone @tagtwo -contains maybe" + Then we should get no error + And the output should contain "maybe" + + Examples: configs + | config | + | basic_onefile | + | basic_folder | + | basic_dayone | + + Scenario Outline: Searching for a string within NOT tag results + Given we use the config ".yaml" + When we run "jrnl -not @tagone -contains lonesome" + Then we should get no error + And the output should contain "lonesome" + + Examples: configs + | config | + | basic_onefile | + | basic_folder | + | basic_dayone | + + Scenario Outline: Searching for dates + Given we use the config ".yaml" + When we run "jrnl -on 2020-08-31 --short" + Then the output should be "2020-08-31 14:32 A second entry in what I hope to be a long series." + Then we flush the output + When we run "jrnl -on 'august 31 2020' --short" + Then the output should be "2020-08-31 14:32 A second entry in what I hope to be a long series." + + Examples: configs + | config | + | basic_onefile | + | basic_folder | + | basic_dayone | + + Scenario: Out of order entries to a Folder journal should be listed in date order + Given we use the config "empty_folder.yaml" + When we run "jrnl 3/7/2014 4:37pm: Second entry of journal." + Then we should see the message "Entry added" + When we run "jrnl 23 July 2013: Testing folder journal." + Then we should see the message "Entry added" + When we run "jrnl -2" + Then the output should be + """ + 2013-07-23 09:00 Testing folder journal. + + 2014-03-07 16:37 Second entry of journal. + """ + + Scenario Outline: Searching for all tags should show counts of each tag + Given we use the config ".yaml" + When we run "jrnl --tags" + Then we should get no error + And the output should be + """ + @tagtwo : 2 + @tagone : 2 + @tagthree : 1 + @ipsum : 1 + """ + + Examples: configs + | config | + | basic_onefile | + | basic_folder | + | basic_dayone | + + Scenario Outline: Filtering journals should also filter tags + Given we use the config ".yaml" + When we run "jrnl -from 'september 2020' --tags" + Then we should get no error + And the output should be + """ + @tagthree : 1 + @tagone : 1 + """ + + Examples: configs + | config | + | basic_onefile | + | basic_folder | + | basic_dayone | + + Scenario Outline: Excluding a tag should filter out all entries with that tag + Given we use the config ".yaml" + When we run "jrnl --tags -not @tagtwo" + Then the output should be + """ + @tagthree : 1 + @tagone : 1 + """ + + Examples: configs + | config | + | basic_onefile | + | basic_folder | + | basic_dayone | + + Scenario Outline: Excluding multiple tags should filter out all entries with those tags + Given we use the config ".yaml" + When we run "jrnl --tags -not @tagone -not @tagthree" + Then the output should be + """ + @tagtwo : 1 + """ + + Examples: configs + | config | + | basic_onefile | + | basic_folder | + | basic_dayone | + + Scenario: DayOne tag searching should work with tags containing a mixture of upper and lower case. + # https://github.com/jrnl-org/jrnl/issues/354 + Given we use the config "dayone.yaml" + When we run "jrnl @plAy" + Then the output should contain "2013-05-17 11:39 This entry has tags!" + + Scenario: Loading a sample journal + Given we use the config "simple.yaml" + When we run "jrnl -2" + Then we should get no error + And the output should be + """ + 2013-06-09 15:39 My first entry. + | Everything is alright + + 2013-06-10 15:40 Life is good. + | But I'm better. + """ + + Scenario Outline: Searching by month + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl -month 9 --short" + Then the output should be "2020-09-24 09:14 The third entry finally after weeks without writing." + And we flush the output + When we run "jrnl -month Sept --short" + Then the output should be "2020-09-24 09:14 The third entry finally after weeks without writing." + And we flush the output + When we run "jrnl -month September --short" + Then the output should be "2020-09-24 09:14 The third entry finally after weeks without writing." + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario Outline: Searching by day + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl -day 31 --short" + Then the output should be "2020-08-31 14:32 A second entry in what I hope to be a long series." + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario Outline: Searching by year + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl 2019-01-01 01:01: I like this year." + And we run "jrnl -year 2019 --short" + Then the output should be "2019-01-01 01:01 I like this year." + And we flush the output + When we run "jrnl -year 19 --short" + Then the output should be "2019-01-01 01:01 I like this year." + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario Outline: Combining month, day, and year search terms + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl -month 08 -day 29 --short" + Then the output should be "2020-08-29 11:11 Entry the first." + And we flush the output + When we run "jrnl -day 29 -year 2020 --short" + Then the output should be "2020-08-29 11:11 Entry the first." + And we flush the output + When we run "jrnl -month 09 -year 2020 --short" + Then the output should be "2020-09-24 09:14 The third entry finally after weeks without writing." + And we flush the output + When we run "jrnl -month 08 -day 29 -year 2020 --short" + Then the output should be "2020-08-29 11:11 Entry the first." + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario Outline: Searching today in history + Given we use the config ".yaml" + And we use the password "test" if prompted + And we set current date and time to "2020-08-31 14:32" + When we run "jrnl 2019-08-31 01:01: Hi, from last year." + And we run "jrnl -today-in-history --short" + Then the output should be + """ + 2019-08-31 01:01 Hi, from last year. + 2020-08-31 14:32 A second entry in what I hope to be a long series. + """ + + Examples: configs + | config | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario: Loading a DayOne Journal + Given we use the config "dayone.yaml" + When we run "jrnl -from 'feb 2013'" + Then we should get no error + And the output should be + """ + 2013-05-17 11:39 This entry has tags! + + 2013-06-17 20:38 This entry has a location. + + 2013-07-17 11:38 This entry is starred! + """ diff --git a/tests/features/star.feature b/tests/features/star.feature new file mode 100644 index 00000000..f0188056 --- /dev/null +++ b/tests/features/star.feature @@ -0,0 +1,35 @@ +Feature: Starring entries + + Scenario Outline: Starring an entry will mark it in the journal file + Given we use the config ".yaml" + When we run "jrnl 20 july 2013 *: Best day of my life!" + Then we should see the message "Entry added" + When we run "jrnl -on 2013-07-20 -starred" + Then the output should contain "2013-07-20 09:00 Best day of my life!" + + Examples: configs + | config_file | + | simple | + | empty_folder | + | dayone | + + Scenario Outline: Filtering by starred entries will show only starred entries + Given we use the config ".yaml" + When we run "jrnl -starred" + Then the output should be empty + When we run "jrnl 20 july 2013 *: Best day of my life!" + When we run "jrnl -starred" + Then the output should be "2013-07-20 09:00 Best day of my life!" + + Examples: configs + | config_file | + | simple | + | empty_folder | + | dayone_empty | + + Scenario: Starring an entry will mark it in an encrypted journal + Given we use the config "encrypted.yaml" + When we run "jrnl 20 july 2013 *: Best day of my life!" and enter "bad doggie no biscuit" + Then we should see the message "Entry added" + When we run "jrnl -on 2013-07-20 -starred" and enter "bad doggie no biscuit" + Then the output should contain "2013-07-20 09:00 Best day of my life!" diff --git a/tests/features/tag.feature b/tests/features/tag.feature new file mode 100644 index 00000000..b7b687b5 --- /dev/null +++ b/tests/features/tag.feature @@ -0,0 +1,53 @@ +Feature: Tagging +# See search.feature for tag-related searches +# And format.feature for tag-related output + + Scenario Outline: Tags should allow certain special characters such as /, +, # + Given we use the config ".yaml" + When we run "jrnl 2020-09-26: This is an entry about @os/2 and @c++ and @c#" + When we run "jrnl --tags -on 2020-09-26" + Then we should get no error + And the output should be + """ + @os/2 : 1 + @c++ : 1 + @c# : 1 + """ + + Examples: configs + | config | + | basic_onefile | + | basic_folder | + | basic_dayone | + + Scenario Outline: Emails addresses should not be parsed as tags + Given we use the config ".yaml" + When we run "jrnl 2020-09-26: The email address test@example.com does not seem to work for me" + When we run "jrnl 2020-09-26: The email address test@example.org also does not work for me" + When we run "jrnl 2020-09-26: I tried test@example.org and test@example.edu too" + Then we flush the output + When we run "jrnl --tags -on 2020-09-26" + Then we should get no error + And the output should be "[No tags found in journal.]" + + Examples: configs + | config | + | basic_onefile | + | basic_folder | + | basic_dayone | + + Scenario Outline: Entry can start and end with tags + Given we use the config ".yaml" + When we run "jrnl 2020-09-26: @foo came over, we went to a @bar" + When we run "jrnl --tags -on 2020-09-26" + Then the output should be + """ + @foo : 1 + @bar : 1 + """ + + Examples: configs + | config | + | basic_onefile | + | basic_folder | + | basic_dayone | diff --git a/tests/features/templates/extension.md b/tests/features/templates/extension.md new file mode 100644 index 00000000..e69de29b diff --git a/tests/features/upgrade.feature b/tests/features/upgrade.feature new file mode 100644 index 00000000..fda47363 --- /dev/null +++ b/tests/features/upgrade.feature @@ -0,0 +1,71 @@ +Feature: Upgrading Journals from 1.x.x to 2.x.x + + Scenario: Upgrade and parse journals with square brackets + Given we use the config "upgrade_from_195.json" + When we run "jrnl -9" and enter "Y" + Then the journal should have 2 entries + And the output should contain + """ + 2010-06-10 15:00 A life without chocolate is like a bad analogy. + """ + And the output should contain + """ + 2013-06-10 15:40 He said "[this] is the best time to be alive". + """ + + Scenario: Upgrading a journal encrypted with jrnl 1.x + Given we use the config "encrypted_old.json" + When we run "jrnl -n 1" and enter + """ + Y + bad doggie no biscuit + bad doggie no biscuit + """ + Then we should be prompted for a password + And the output should contain "2013-06-10 15:40 Life is good" + + Scenario: Upgrading a config without colors to colors + Given we use the config "no_colors.yaml" + When we run "jrnl -n 1" + Then the config should have "colors" set to + """ + { + 'date':'none', + 'title':'none', + 'body':'none', + 'tags':'none' + } + """ + + Scenario: Upgrade and parse journals with little endian date format + Given we use the config "upgrade_from_195_little_endian_dates.json" + When we run "jrnl -9" and enter "Y" + Then the journal should have 2 entries + And the output should contain + """ + 10.06.2010 15:00 A life without chocolate is like a bad analogy. + """ + And the output should contain + """ + 10.06.2013 15:40 He said "[this] is the best time to be alive". + """ + + Scenario: Upgrade with missing journal + Given we use the config "upgrade_from_195_with_missing_journal.json" + When we run "jrnl -ls" and enter + """" + Y + """ + Then the output should contain "Error: features/journals/missing.journal does not exist." + And we should get no error + + Scenario: Upgrade with missing encrypted journal + Given we use the config "upgrade_from_195_with_missing_encrypted_journal.json" + When we run "jrnl -ls" and enter + """ + Y + bad doggie no biscuit + """ + Then the output should contain "Error: features/journals/missing.journal does not exist." + And the error output should contain "We're all done" + And we should get no error diff --git a/tests/features/write.feature b/tests/features/write.feature new file mode 100644 index 00000000..eb22e480 --- /dev/null +++ b/tests/features/write.feature @@ -0,0 +1,216 @@ +Feature: Writing new entries. + + Scenario Outline: Multiline entry with punctuation should keep title punctuation + Given we use the config ".yaml" + And we use the password "bad doggie no biscuit" if prompted + When we run "jrnl This is. the title\\n This is the second line" + And we run "jrnl -n 1" + Then the output should contain "This is. the title" + + Examples: configs + | config_file | + | simple | + | empty_folder | + | dayone | + | encrypted | + + Scenario Outline: Single line entry with period should be split at period + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl This is. the title" + And we run "jrnl -1" + Then the output should contain "| the title" + + Examples: configs + | config_file | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario Outline: CJK entry should be split at fullwidth period without following space. + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl 七転び。八起き" + And we run "jrnl -1" + Then the output should contain "| 八起き" + + Examples: configs + | config_file | + | basic_onefile | + | basic_encrypted | + | basic_folder | + | basic_dayone | + + Scenario Outline: Writing an entry from command line should store the entry + Given we use the config ".yaml" + And we use the password "bad doggie no biscuit" if prompted + When we run "jrnl 23 july 2013: A cold and stormy day. I ate crisps on the sofa." + Then we should see the message "Entry added" + When we run "jrnl -n 1" + Then the output should contain "2013-07-23 09:00 A cold and stormy day." + + Examples: configs + | config_file | + | simple | + | empty_folder | + | dayone | + | encrypted | + + Scenario Outline: Writing a partial entry from command line with edit flag should go to the editor + Given we use the config ".yaml" + And we use the password "test" if prompted + When we run "jrnl this is a partial --edit" + Then we should see the message "Entry added" + Then the editor should have been called + And the editor file content should be + """ + this is a partial + """ + When we run "jrnl -n 1" + Then the output should contain "this is a partial" + + Examples: configs + | config_file | + | basic_onefile | + | basic_encrypted | + | basic_dayone | + | basic_folder | + + Scenario Outline: Writing an empty entry from the editor should yield "Nothing saved to file" message + Given we use the config ".yaml" + And we use the password "test" if prompted + When we open the editor and enter nothing + Then the error output should contain "[Nothing saved to file]" + + Examples: configs + | config_file | + | editor | + | editor_empty_folder | + | dayone | + | basic_encrypted | + | basic_onefile | + + @skip + Scenario Outline: Writing an empty entry from the command line with no editor should yield nothing + Given we use the config ".yaml" + And we use the password "bad doggie no biscuit" if prompted + When we run "jrnl" and enter nothing + Then the output should be empty + And the error output should contain "Writing Entry; on a blank line" + And the editor should not have been called + + Examples: configs + | config_file | + | simple | + | empty_folder | + | encrypted | + # | dayone | @todo + + Scenario Outline: Writing an entry does not print the entire journal + # https://github.com/jrnl-org/jrnl/issues/87 + Given we use the config ".yaml" + And we use the password "bad doggie no biscuit" if prompted + When we run "jrnl 23 july 2013: A cold and stormy day. I ate crisps on the sofa." + Then we should see the message "Entry added" + When we run "jrnl -n 1" + Then the output should not contain "Life is good" + + Examples: configs + | config_file | + | editor | + | editor_empty_folder | + | dayone | + | encrypted | + + Scenario Outline: Embedded period stays in title + Given we use the config ".yaml" + And we use the password "bad doggie no biscuit" if prompted + When we run "jrnl 04-24-2014: Created a new website - empty.com. Hope to get a lot of traffic." + Then we should see the message "Entry added" + When we run "jrnl -1" + Then the output should be + """ + 2014-04-24 09:00 Created a new website - empty.com. + | Hope to get a lot of traffic. + """ + + Examples: configs + | config_file | + | simple | + | empty_folder | + | dayone | + | encrypted | + + Scenario Outline: Write and read emoji support + Given we use the config ".yaml" + And we use the password "bad doggie no biscuit" if prompted + When we run "jrnl 23 july 2013: 🌞 sunny day. Saw an 🐘" + Then we should see the message "Entry added" + When we run "jrnl -n 1" + Then the output should contain "🌞" + And the output should contain "🐘" + + Examples: configs + | config_file | + | simple | + | empty_folder | + | dayone | + | encrypted | + + Scenario Outline: Writing an entry at the prompt (no editor) should store the entry + Given we use the config ".yaml" + And we use the password "bad doggie no biscuit" if prompted + When we run "jrnl" and enter "25 jul 2013: I saw Elvis. He's alive." + Then we should get no error + When we run "jrnl -on '2013-07-25'" + Then the output should contain "2013-07-25 09:00 I saw Elvis." + And the output should contain "| He's alive." + + Examples: configs + | config_file | + | simple | + | empty_folder | + | encrypted | + + @todo + Scenario: Writing an entry at the prompt (no editor) in DayOne journal + # Need to test DayOne w/out an editor + + Scenario: Writing into Dayone + Given we use the config "dayone.yaml" + When we run "jrnl 01 may 1979: Being born hurts." + And we run "jrnl -until 1980" + Then the output should be "1979-05-01 09:00 Being born hurts." + + Scenario: Writing into Dayone adds extended metadata + Given we use the config "dayone.yaml" + When we run "jrnl 01 may 1979: Being born hurts." + And we run "jrnl --export json" + Then "entries" in the json output should have 5 elements + And the json output should contain entries.0.creator.software_agent + And the json output should contain entries.0.creator.os_agent + And the json output should contain entries.0.creator.host_name + And the json output should contain entries.0.creator.generation_date + And the json output should contain entries.0.creator.device_agent + And "entries.0.creator.software_agent" in the json output should contain "jrnl" + + # fails when system time is UTC (as on Travis-CI) + @skip + Scenario: Title with an embedded period on DayOne journal + Given we use the config "dayone.yaml" + When we run "jrnl 04-24-2014: "Ran 6.2 miles today in 1:02:03. I'm feeling sore because I forgot to stretch."" + Then we should see the message "Entry added" + When we run "jrnl -1" + Then the output should be + """ + 2014-04-24 09:00 Ran 6.2 miles today in 1:02:03. + | I'm feeling sore because I forgot to stretch. + """ + + Scenario: Opening an folder that's not a DayOne folder should treat as folder journal + Given we use the config "empty_folder.yaml" + When we run "jrnl 23 july 2013: Testing folder journal." + Then we should see the message "Entry added" + When we run "jrnl -1" + Then the output should be "2013-07-23 09:00 Testing folder journal." diff --git a/tests/step_defs/__init__.py b/tests/step_defs/__init__.py new file mode 100644 index 00000000..46468510 --- /dev/null +++ b/tests/step_defs/__init__.py @@ -0,0 +1,3 @@ +import sys + +sys.path.append("..") diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py new file mode 100644 index 00000000..cf6a2d5e --- /dev/null +++ b/tests/step_defs/conftest.py @@ -0,0 +1,111 @@ +# Copyright (C) 2012-2021 jrnl contributors +# License: https://www.gnu.org/licenses/gpl-3.0.html + +import shutil +import os +import re + +import pytest +from pytest_bdd import given +from pytest_bdd import then +from pytest_bdd import when +from pytest_bdd.parsers import parse +from unittest.mock import patch + +from jrnl import __version__ +from jrnl.os_compat import split_args +from jrnl.cli import cli + +WORKING_DIR = '' +TEMP_DIR = '' + +# ----- FIXTURES ----- # +@pytest.fixture +def cli_run(): + return dict(status=0, stdout=None, stderr=None) + + +def get_working_dirs(request): + CWD = request.config.rootpath + return os.path.join(CWD, 'tests', '.current_test'), CWD + + +# ----- HOOKS ----- # +def pytest_bdd_before_scenario(request, feature, scenario): + """Before each scenario, backup all config and journal test data.""" + global TEMP_DIR + global WORKING_DIR + TEMP_DIR, WORKING_DIR = get_working_dirs(request) + + if not os.path.exists(TEMP_DIR): + os.mkdir(TEMP_DIR) + + +def pytest_bdd_after_scenario(request, feature, scenario): + """After each scenario, restore all test data and remove working_dirs.""" + TEMP_DIR, WORKING_DIR = get_working_dirs(request) + + if os.path.exists(TEMP_DIR): + shutil.rmtree(TEMP_DIR) + + +# ----- STEPS ----- # +@given(parse('we use the config "{config_file}"'), target_fixture="config_path") +def set_config(config_file): + # Copy the config file over + config_source = os.path.join(WORKING_DIR, 'features', 'data', 'configs', config_file) + config_dest = os.path.join(TEMP_DIR, 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, 'features', 'data', 'journals') + journal_dest = os.path.join(TEMP_DIR, 'features', 'journals') + shutil.copytree(journal_source, journal_dest, dirs_exist_ok=True) + + # @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 + + +@when(parse('we run "{command}"')) +def run(command, config_path, cli_run, capsys): + args = split_args(command) + status = 0 + + # fmt: off + # see: https://github.com/psf/black/issues/664 + with \ + patch("sys.argv", args), \ + patch("jrnl.config.get_config_path", side_effect=lambda: config_path), \ + patch("jrnl.install.get_config_path", side_effect=lambda: config_path) \ + : + try: + cli(args[1:]) + except SystemExit as e: + status = e.code + # fmt: on + + cli_run['status'] = status + captured = capsys.readouterr() + cli_run['stdout'] = captured.out + cli_run['stderr'] = captured.err + + +@then("we should get no error") +def no_error(cli_run): + assert cli_run['status'] == 0, cli_run['status'] + + +@then(parse('the output should match "{regex}"')) +def matches_std_output(regex, cli_run): + out = cli_run['stdout'] + matches = re.findall(regex, out) + assert ( + matches + ), f"\nRegex didn't match:\n{regex}\n{str(out)}\n{str(matches)}" diff --git a/tests/step_defs/test_features.py b/tests/step_defs/test_features.py new file mode 100644 index 00000000..d670f9c9 --- /dev/null +++ b/tests/step_defs/test_features.py @@ -0,0 +1,3 @@ +from pytest_bdd import scenarios + +scenarios("../features/core.feature") From 530190df7adff163c48ad7fd33d14d6ad1d877cc Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 13 Feb 2021 17:43:42 -0800 Subject: [PATCH 090/215] Implement handling of temp and working dirs Pytest-bdd uses fixtures to handle most things. This makes a fixture that will create a temp directory for the tests to run in. Co-authored-by: Micah Jerome Ellison --- tests/step_defs/conftest.py | 66 ++++++++++++++----------------------- 1 file changed, 24 insertions(+), 42 deletions(-) diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index cf6a2d5e..93482ce9 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -4,8 +4,9 @@ import shutil import os import re +import tempfile -import pytest +from pytest import fixture from pytest_bdd import given from pytest_bdd import then from pytest_bdd import when @@ -16,52 +17,35 @@ from jrnl import __version__ from jrnl.os_compat import split_args from jrnl.cli import cli -WORKING_DIR = '' -TEMP_DIR = '' - # ----- FIXTURES ----- # -@pytest.fixture +@fixture def cli_run(): - return dict(status=0, stdout=None, stderr=None) + return {"status": 0, "stdout": None, "stderr": None} +@fixture +def temp_dir(): + return tempfile.TemporaryDirectory() -def get_working_dirs(request): - CWD = request.config.rootpath - return os.path.join(CWD, 'tests', '.current_test'), CWD - - -# ----- HOOKS ----- # -def pytest_bdd_before_scenario(request, feature, scenario): - """Before each scenario, backup all config and journal test data.""" - global TEMP_DIR - global WORKING_DIR - TEMP_DIR, WORKING_DIR = get_working_dirs(request) - - if not os.path.exists(TEMP_DIR): - os.mkdir(TEMP_DIR) - - -def pytest_bdd_after_scenario(request, feature, scenario): - """After each scenario, restore all test data and remove working_dirs.""" - TEMP_DIR, WORKING_DIR = get_working_dirs(request) - - if os.path.exists(TEMP_DIR): - shutil.rmtree(TEMP_DIR) +@fixture +def working_dir(request): + return os.path.join(request.config.rootpath, "tests") # ----- STEPS ----- # @given(parse('we use the config "{config_file}"'), target_fixture="config_path") -def set_config(config_file): +def set_config(config_file, temp_dir, working_dir): # Copy the config file over - config_source = os.path.join(WORKING_DIR, 'features', 'data', 'configs', config_file) - config_dest = os.path.join(TEMP_DIR, config_file) + config_source = os.path.join( + working_dir, "features", "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, 'features', 'data', 'journals') - journal_dest = os.path.join(TEMP_DIR, 'features', 'journals') - shutil.copytree(journal_source, journal_dest, dirs_exist_ok=True) + journal_source = os.path.join(working_dir, "features", "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 @@ -91,21 +75,19 @@ def run(command, config_path, cli_run, capsys): status = e.code # fmt: on - cli_run['status'] = status + cli_run["status"] = status captured = capsys.readouterr() - cli_run['stdout'] = captured.out - cli_run['stderr'] = captured.err + cli_run["stdout"] = captured.out + cli_run["stderr"] = captured.err @then("we should get no error") def no_error(cli_run): - assert cli_run['status'] == 0, cli_run['status'] + assert cli_run["status"] == 0, cli_run["status"] @then(parse('the output should match "{regex}"')) def matches_std_output(regex, cli_run): - out = cli_run['stdout'] + out = cli_run["stdout"] matches = re.findall(regex, out) - assert ( - matches - ), f"\nRegex didn't match:\n{regex}\n{str(out)}\n{str(matches)}" + assert matches, f"\nRegex didn't match:\n{regex}\n{str(out)}\n{str(matches)}" From 0b50ae1be064e32ca07470fe1b9020627a52dea7 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 13 Feb 2021 17:53:32 -0800 Subject: [PATCH 091/215] Rename features directory to data This is more inline with pytest standards Co-authored-by: Micah Jerome Ellison --- .../configs/basic_dayone.yaml | 0 .../configs/basic_encrypted.yaml | 0 .../configs/basic_folder.yaml | 0 .../configs/basic_onefile.yaml | 0 .../{features => data}/configs/brackets.yaml | 0 tests/{features => data}/configs/bug153.yaml | 0 tests/{features => data}/configs/bug343.yaml | 0 tests/{features => data}/configs/bug780.yaml | 0 tests/{features => data}/configs/dayone.yaml | 0 .../configs/dayone_empty.yaml | 0 .../{features => data}/configs/deletion.yaml | 0 .../configs/deletion_filters.yaml | 0 .../configs/editor-args.yaml | 0 tests/{features => data}/configs/editor.yaml | 0 .../configs/editor_empty_folder.yaml | 0 .../configs/editor_encrypted.yaml | 0 .../configs/empty_folder.yaml | 0 .../{features => data}/configs/encrypted.yaml | 0 .../configs/encrypted_old.json | 0 .../configs/encrypted_old.yaml | 0 .../{features => data}/configs/format_md.yaml | 0 .../configs/format_text.yaml | 0 .../configs/invalid_color.yaml | 0 .../configs/little_endian_dates.yaml | 0 .../configs/markdown-headings-335.yaml | 0 .../configs/missing_directory.yaml | 0 .../configs/missing_journal.yaml | 0 .../configs/mostlyreadabledates.yaml | 0 .../configs/multiline-tags.yaml | 0 .../{features => data}/configs/multiline.yaml | 0 .../{features => data}/configs/multiple.yaml | 0 .../{features => data}/configs/no_colors.yaml | 0 tests/{features => }/data/configs/simple.yaml | 0 .../{features => data}/configs/tags-216.yaml | 0 .../{features => data}/configs/tags-237.yaml | 0 tests/{features => data}/configs/tags.yaml | 0 .../configs/unreadabledates.yaml | 0 .../configs/upgrade_from_195.json | 0 .../upgrade_from_195_little_endian_dates.json | 0 ...om_195_with_missing_encrypted_journal.json | 0 ...upgrade_from_195_with_missing_journal.json | 0 .../D04D335AFED711EABA18FAFFC2100C3D.doentry | 0 .../FC8A86CAFED711EA8892FAFFC2100C3D.doentry | 0 .../FD8ABC8EFED711EABC35FAFFC2100C3D.doentry | 0 .../data/journals/basic_encrypted.journal | 0 .../data/journals/basic_folder/2020/08/29.txt | 0 .../data/journals/basic_folder/2020/08/31.txt | 0 .../data/journals/basic_folder/2020/09/24.txt | 0 .../data/journals/basic_onefile.journal | 0 .../data/journals/brackets.journal | 0 .../B40EE704E15846DE8D45C44118A4D511.doentry | 0 .../B40EE704E15846DE8D45C44118A4D512.doentry | 0 .../48A25033B34047C591160A4480197D8B.doentry | 0 .../044F3747A38546168B572C2E3F217FA2.doentry | 0 .../0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry | 0 .../422BC895507944A291E6FC44FC6B8BFC.doentry | 0 .../4BB1F46946AD439996C9B59DE7C4DDC1.doentry | 0 .../dayone_empty.dayone/entries/empty.txt | 0 .../data/journals/deletion.journal | 0 .../data/journals/deletion_filters.journal | 0 .../data/journals/empty_folder/empty | 0 .../data/journals/encrypted.journal | 0 .../journals/encrypted_jrnl-1-9-5.journal | Bin .../data/journals/little_endian_dates.journal | 0 .../journals/markdown-headings-335.journal | 0 .../data/journals/mostlyreadabledates.journal | 0 .../data/journals/multiline-tags.journal | 0 .../data/journals/multiline.journal | 0 .../data/journals/simple.journal | 0 .../data/journals/simple_jrnl-1-9-5.journal | 0 ...ple_jrnl-1-9-5_little_endian_dates.journal | 0 .../data/journals/tags-216.journal | 0 .../data/journals/tags-237.journal | 0 .../{features => }/data/journals/tags.journal | 0 .../data/journals/unreadabledates.journal | 0 .../{features => }/data/journals/work.journal | 0 .../data/templates/sample.template | 0 .../configs/editor_markdown_extension.yaml | 18 ------ tests/features/configs/simple.yaml | 18 ------ tests/features/core.feature | 1 + tests/features/data/configs/basic_dayone.yaml | 17 ----- .../data/configs/basic_encrypted.yaml | 17 ----- tests/features/data/configs/basic_folder.yaml | 17 ----- .../features/data/configs/basic_onefile.yaml | 17 ----- tests/features/data/configs/brackets.yaml | 12 ---- tests/features/data/configs/bug153.yaml | 17 ----- tests/features/data/configs/bug343.yaml | 13 ---- tests/features/data/configs/bug780.yaml | 12 ---- tests/features/data/configs/dayone.yaml | 12 ---- tests/features/data/configs/dayone_empty.yaml | 17 ----- tests/features/data/configs/deletion.yaml | 12 ---- .../data/configs/deletion_filters.yaml | 12 ---- tests/features/data/configs/editor-args.yaml | 12 ---- tests/features/data/configs/editor.yaml | 12 ---- .../data/configs/editor_empty_folder.yaml | 12 ---- .../data/configs/editor_encrypted.yaml | 17 ----- tests/features/data/configs/empty_folder.yaml | 12 ---- tests/features/data/configs/encrypted.yaml | 12 ---- .../features/data/configs/encrypted_old.json | 13 ---- .../features/data/configs/encrypted_old.yaml | 11 ---- tests/features/data/configs/format_md.yaml | 19 ------ tests/features/data/configs/format_text.yaml | 19 ------ .../features/data/configs/invalid_color.yaml | 17 ----- .../data/configs/little_endian_dates.yaml | 12 ---- .../data/configs/markdown-headings-335.yaml | 17 ----- .../data/configs/missing_directory.yaml | 17 ----- .../data/configs/missing_journal.yaml | 17 ----- .../data/configs/mostlyreadabledates.yaml | 12 ---- .../features/data/configs/multiline-tags.yaml | 17 ----- tests/features/data/configs/multiline.yaml | 17 ----- tests/features/data/configs/multiple.yaml | 18 ------ tests/features/data/configs/no_colors.yaml | 12 ---- tests/features/data/configs/tags-216.yaml | 17 ----- tests/features/data/configs/tags-237.yaml | 17 ----- tests/features/data/configs/tags.yaml | 17 ----- .../data/configs/unreadabledates.yaml | 17 ----- .../data/configs/upgrade_from_195.json | 11 ---- .../upgrade_from_195_little_endian_dates.json | 11 ---- ...om_195_with_missing_encrypted_journal.json | 11 ---- ...upgrade_from_195_with_missing_journal.json | 11 ---- tests/features/environment.py | 0 .../D04D335AFED711EABA18FAFFC2100C3D.doentry | 53 ---------------- .../FC8A86CAFED711EA8892FAFFC2100C3D.doentry | 55 ----------------- .../FD8ABC8EFED711EABC35FAFFC2100C3D.doentry | 44 ------------- .../features/journals/basic_encrypted.journal | 1 - .../journals/basic_folder/2020/08/29.txt | 19 ------ .../journals/basic_folder/2020/08/31.txt | 23 ------- .../journals/basic_folder/2020/09/24.txt | 11 ---- tests/features/journals/basic_onefile.journal | 58 ------------------ tests/features/journals/brackets.journal | 2 - .../B40EE704E15846DE8D45C44118A4D511.doentry | 56 ----------------- .../B40EE704E15846DE8D45C44118A4D512.doentry | 52 ---------------- .../48A25033B34047C591160A4480197D8B.doentry | 33 ---------- .../044F3747A38546168B572C2E3F217FA2.doentry | 34 ---------- .../0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry | 46 -------------- .../422BC895507944A291E6FC44FC6B8BFC.doentry | 31 ---------- .../4BB1F46946AD439996C9B59DE7C4DDC1.doentry | 29 --------- .../dayone_empty.dayone/entries/empty.txt | 1 - tests/features/journals/deletion.journal | 5 -- .../journals/deletion_filters.journal | 14 ----- tests/features/journals/empty_folder/empty | 1 - tests/features/journals/encrypted.journal | 1 - .../journals/encrypted_jrnl-1-9-5.journal | Bin 128 -> 0 bytes .../journals/little_endian_dates.journal | 5 -- .../journals/markdown-headings-335.journal | 42 ------------- .../journals/mostlyreadabledates.journal | 8 --- .../features/journals/multiline-tags.journal | 7 --- tests/features/journals/multiline.journal | 5 -- tests/features/journals/simple.journal | 5 -- .../journals/simple_jrnl-1-9-5.journal | 13 ---- ...ple_jrnl-1-9-5_little_endian_dates.journal | 13 ---- tests/features/journals/tags-216.journal | 2 - tests/features/journals/tags-237.journal | 3 - tests/features/journals/tags.journal | 8 --- .../features/journals/unreadabledates.journal | 5 -- tests/features/journals/work.journal | 0 tests/features/templates/extension.md | 0 tests/step_defs/conftest.py | 6 +- 158 files changed, 4 insertions(+), 1306 deletions(-) rename tests/{features => data}/configs/basic_dayone.yaml (100%) rename tests/{features => data}/configs/basic_encrypted.yaml (100%) rename tests/{features => data}/configs/basic_folder.yaml (100%) rename tests/{features => data}/configs/basic_onefile.yaml (100%) rename tests/{features => data}/configs/brackets.yaml (100%) rename tests/{features => data}/configs/bug153.yaml (100%) rename tests/{features => data}/configs/bug343.yaml (100%) rename tests/{features => data}/configs/bug780.yaml (100%) rename tests/{features => data}/configs/dayone.yaml (100%) rename tests/{features => data}/configs/dayone_empty.yaml (100%) rename tests/{features => data}/configs/deletion.yaml (100%) rename tests/{features => data}/configs/deletion_filters.yaml (100%) rename tests/{features => data}/configs/editor-args.yaml (100%) rename tests/{features => data}/configs/editor.yaml (100%) rename tests/{features => data}/configs/editor_empty_folder.yaml (100%) rename tests/{features => data}/configs/editor_encrypted.yaml (100%) rename tests/{features => data}/configs/empty_folder.yaml (100%) rename tests/{features => data}/configs/encrypted.yaml (100%) rename tests/{features => data}/configs/encrypted_old.json (100%) rename tests/{features => data}/configs/encrypted_old.yaml (100%) rename tests/{features => data}/configs/format_md.yaml (100%) rename tests/{features => data}/configs/format_text.yaml (100%) rename tests/{features => data}/configs/invalid_color.yaml (100%) rename tests/{features => data}/configs/little_endian_dates.yaml (100%) rename tests/{features => data}/configs/markdown-headings-335.yaml (100%) rename tests/{features => data}/configs/missing_directory.yaml (100%) rename tests/{features => data}/configs/missing_journal.yaml (100%) rename tests/{features => data}/configs/mostlyreadabledates.yaml (100%) rename tests/{features => data}/configs/multiline-tags.yaml (100%) rename tests/{features => data}/configs/multiline.yaml (100%) rename tests/{features => data}/configs/multiple.yaml (100%) rename tests/{features => data}/configs/no_colors.yaml (100%) rename tests/{features => }/data/configs/simple.yaml (100%) rename tests/{features => data}/configs/tags-216.yaml (100%) rename tests/{features => data}/configs/tags-237.yaml (100%) rename tests/{features => data}/configs/tags.yaml (100%) rename tests/{features => data}/configs/unreadabledates.yaml (100%) rename tests/{features => data}/configs/upgrade_from_195.json (100%) rename tests/{features => data}/configs/upgrade_from_195_little_endian_dates.json (100%) rename tests/{features => data}/configs/upgrade_from_195_with_missing_encrypted_journal.json (100%) rename tests/{features => data}/configs/upgrade_from_195_with_missing_journal.json (100%) rename tests/{features => }/data/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry (100%) rename tests/{features => }/data/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry (100%) rename tests/{features => }/data/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry (100%) rename tests/{features => }/data/journals/basic_encrypted.journal (100%) rename tests/{features => }/data/journals/basic_folder/2020/08/29.txt (100%) rename tests/{features => }/data/journals/basic_folder/2020/08/31.txt (100%) rename tests/{features => }/data/journals/basic_folder/2020/09/24.txt (100%) rename tests/{features => }/data/journals/basic_onefile.journal (100%) rename tests/{features => }/data/journals/brackets.journal (100%) rename tests/{features => }/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry (100%) rename tests/{features => }/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry (100%) rename tests/{features => }/data/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry (100%) rename tests/{features => }/data/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry (100%) rename tests/{features => }/data/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry (100%) rename tests/{features => }/data/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry (100%) rename tests/{features => }/data/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry (100%) rename tests/{features => }/data/journals/dayone_empty.dayone/entries/empty.txt (100%) rename tests/{features => }/data/journals/deletion.journal (100%) rename tests/{features => }/data/journals/deletion_filters.journal (100%) rename tests/{features => }/data/journals/empty_folder/empty (100%) rename tests/{features => }/data/journals/encrypted.journal (100%) rename tests/{features => }/data/journals/encrypted_jrnl-1-9-5.journal (100%) rename tests/{features => }/data/journals/little_endian_dates.journal (100%) rename tests/{features => }/data/journals/markdown-headings-335.journal (100%) rename tests/{features => }/data/journals/mostlyreadabledates.journal (100%) rename tests/{features => }/data/journals/multiline-tags.journal (100%) rename tests/{features => }/data/journals/multiline.journal (100%) rename tests/{features => }/data/journals/simple.journal (100%) rename tests/{features => }/data/journals/simple_jrnl-1-9-5.journal (100%) rename tests/{features => }/data/journals/simple_jrnl-1-9-5_little_endian_dates.journal (100%) rename tests/{features => }/data/journals/tags-216.journal (100%) rename tests/{features => }/data/journals/tags-237.journal (100%) rename tests/{features => }/data/journals/tags.journal (100%) rename tests/{features => }/data/journals/unreadabledates.journal (100%) rename tests/{features => }/data/journals/work.journal (100%) rename tests/{features => }/data/templates/sample.template (100%) delete mode 100644 tests/features/configs/editor_markdown_extension.yaml delete mode 100644 tests/features/configs/simple.yaml delete mode 100644 tests/features/data/configs/basic_dayone.yaml delete mode 100644 tests/features/data/configs/basic_encrypted.yaml delete mode 100644 tests/features/data/configs/basic_folder.yaml delete mode 100644 tests/features/data/configs/basic_onefile.yaml delete mode 100644 tests/features/data/configs/brackets.yaml delete mode 100644 tests/features/data/configs/bug153.yaml delete mode 100644 tests/features/data/configs/bug343.yaml delete mode 100644 tests/features/data/configs/bug780.yaml delete mode 100644 tests/features/data/configs/dayone.yaml delete mode 100644 tests/features/data/configs/dayone_empty.yaml delete mode 100644 tests/features/data/configs/deletion.yaml delete mode 100644 tests/features/data/configs/deletion_filters.yaml delete mode 100644 tests/features/data/configs/editor-args.yaml delete mode 100644 tests/features/data/configs/editor.yaml delete mode 100644 tests/features/data/configs/editor_empty_folder.yaml delete mode 100644 tests/features/data/configs/editor_encrypted.yaml delete mode 100644 tests/features/data/configs/empty_folder.yaml delete mode 100644 tests/features/data/configs/encrypted.yaml delete mode 100644 tests/features/data/configs/encrypted_old.json delete mode 100644 tests/features/data/configs/encrypted_old.yaml delete mode 100644 tests/features/data/configs/format_md.yaml delete mode 100644 tests/features/data/configs/format_text.yaml delete mode 100644 tests/features/data/configs/invalid_color.yaml delete mode 100644 tests/features/data/configs/little_endian_dates.yaml delete mode 100644 tests/features/data/configs/markdown-headings-335.yaml delete mode 100644 tests/features/data/configs/missing_directory.yaml delete mode 100644 tests/features/data/configs/missing_journal.yaml delete mode 100644 tests/features/data/configs/mostlyreadabledates.yaml delete mode 100644 tests/features/data/configs/multiline-tags.yaml delete mode 100644 tests/features/data/configs/multiline.yaml delete mode 100644 tests/features/data/configs/multiple.yaml delete mode 100644 tests/features/data/configs/no_colors.yaml delete mode 100644 tests/features/data/configs/tags-216.yaml delete mode 100644 tests/features/data/configs/tags-237.yaml delete mode 100644 tests/features/data/configs/tags.yaml delete mode 100644 tests/features/data/configs/unreadabledates.yaml delete mode 100644 tests/features/data/configs/upgrade_from_195.json delete mode 100644 tests/features/data/configs/upgrade_from_195_little_endian_dates.json delete mode 100644 tests/features/data/configs/upgrade_from_195_with_missing_encrypted_journal.json delete mode 100644 tests/features/data/configs/upgrade_from_195_with_missing_journal.json delete mode 100644 tests/features/environment.py delete mode 100644 tests/features/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry delete mode 100644 tests/features/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry delete mode 100644 tests/features/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry delete mode 100644 tests/features/journals/basic_encrypted.journal delete mode 100644 tests/features/journals/basic_folder/2020/08/29.txt delete mode 100644 tests/features/journals/basic_folder/2020/08/31.txt delete mode 100644 tests/features/journals/basic_folder/2020/09/24.txt delete mode 100644 tests/features/journals/basic_onefile.journal delete mode 100644 tests/features/journals/brackets.journal delete mode 100644 tests/features/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry delete mode 100644 tests/features/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry delete mode 100644 tests/features/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry delete mode 100644 tests/features/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry delete mode 100644 tests/features/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry delete mode 100644 tests/features/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry delete mode 100644 tests/features/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry delete mode 100644 tests/features/journals/dayone_empty.dayone/entries/empty.txt delete mode 100644 tests/features/journals/deletion.journal delete mode 100644 tests/features/journals/deletion_filters.journal delete mode 100644 tests/features/journals/empty_folder/empty delete mode 100644 tests/features/journals/encrypted.journal delete mode 100644 tests/features/journals/encrypted_jrnl-1-9-5.journal delete mode 100644 tests/features/journals/little_endian_dates.journal delete mode 100644 tests/features/journals/markdown-headings-335.journal delete mode 100644 tests/features/journals/mostlyreadabledates.journal delete mode 100644 tests/features/journals/multiline-tags.journal delete mode 100644 tests/features/journals/multiline.journal delete mode 100644 tests/features/journals/simple.journal delete mode 100644 tests/features/journals/simple_jrnl-1-9-5.journal delete mode 100644 tests/features/journals/simple_jrnl-1-9-5_little_endian_dates.journal delete mode 100644 tests/features/journals/tags-216.journal delete mode 100644 tests/features/journals/tags-237.journal delete mode 100644 tests/features/journals/tags.journal delete mode 100644 tests/features/journals/unreadabledates.journal delete mode 100644 tests/features/journals/work.journal delete mode 100644 tests/features/templates/extension.md diff --git a/tests/features/configs/basic_dayone.yaml b/tests/data/configs/basic_dayone.yaml similarity index 100% rename from tests/features/configs/basic_dayone.yaml rename to tests/data/configs/basic_dayone.yaml diff --git a/tests/features/configs/basic_encrypted.yaml b/tests/data/configs/basic_encrypted.yaml similarity index 100% rename from tests/features/configs/basic_encrypted.yaml rename to tests/data/configs/basic_encrypted.yaml diff --git a/tests/features/configs/basic_folder.yaml b/tests/data/configs/basic_folder.yaml similarity index 100% rename from tests/features/configs/basic_folder.yaml rename to tests/data/configs/basic_folder.yaml diff --git a/tests/features/configs/basic_onefile.yaml b/tests/data/configs/basic_onefile.yaml similarity index 100% rename from tests/features/configs/basic_onefile.yaml rename to tests/data/configs/basic_onefile.yaml diff --git a/tests/features/configs/brackets.yaml b/tests/data/configs/brackets.yaml similarity index 100% rename from tests/features/configs/brackets.yaml rename to tests/data/configs/brackets.yaml diff --git a/tests/features/configs/bug153.yaml b/tests/data/configs/bug153.yaml similarity index 100% rename from tests/features/configs/bug153.yaml rename to tests/data/configs/bug153.yaml diff --git a/tests/features/configs/bug343.yaml b/tests/data/configs/bug343.yaml similarity index 100% rename from tests/features/configs/bug343.yaml rename to tests/data/configs/bug343.yaml diff --git a/tests/features/configs/bug780.yaml b/tests/data/configs/bug780.yaml similarity index 100% rename from tests/features/configs/bug780.yaml rename to tests/data/configs/bug780.yaml diff --git a/tests/features/configs/dayone.yaml b/tests/data/configs/dayone.yaml similarity index 100% rename from tests/features/configs/dayone.yaml rename to tests/data/configs/dayone.yaml diff --git a/tests/features/configs/dayone_empty.yaml b/tests/data/configs/dayone_empty.yaml similarity index 100% rename from tests/features/configs/dayone_empty.yaml rename to tests/data/configs/dayone_empty.yaml diff --git a/tests/features/configs/deletion.yaml b/tests/data/configs/deletion.yaml similarity index 100% rename from tests/features/configs/deletion.yaml rename to tests/data/configs/deletion.yaml diff --git a/tests/features/configs/deletion_filters.yaml b/tests/data/configs/deletion_filters.yaml similarity index 100% rename from tests/features/configs/deletion_filters.yaml rename to tests/data/configs/deletion_filters.yaml diff --git a/tests/features/configs/editor-args.yaml b/tests/data/configs/editor-args.yaml similarity index 100% rename from tests/features/configs/editor-args.yaml rename to tests/data/configs/editor-args.yaml diff --git a/tests/features/configs/editor.yaml b/tests/data/configs/editor.yaml similarity index 100% rename from tests/features/configs/editor.yaml rename to tests/data/configs/editor.yaml diff --git a/tests/features/configs/editor_empty_folder.yaml b/tests/data/configs/editor_empty_folder.yaml similarity index 100% rename from tests/features/configs/editor_empty_folder.yaml rename to tests/data/configs/editor_empty_folder.yaml diff --git a/tests/features/configs/editor_encrypted.yaml b/tests/data/configs/editor_encrypted.yaml similarity index 100% rename from tests/features/configs/editor_encrypted.yaml rename to tests/data/configs/editor_encrypted.yaml diff --git a/tests/features/configs/empty_folder.yaml b/tests/data/configs/empty_folder.yaml similarity index 100% rename from tests/features/configs/empty_folder.yaml rename to tests/data/configs/empty_folder.yaml diff --git a/tests/features/configs/encrypted.yaml b/tests/data/configs/encrypted.yaml similarity index 100% rename from tests/features/configs/encrypted.yaml rename to tests/data/configs/encrypted.yaml diff --git a/tests/features/configs/encrypted_old.json b/tests/data/configs/encrypted_old.json similarity index 100% rename from tests/features/configs/encrypted_old.json rename to tests/data/configs/encrypted_old.json diff --git a/tests/features/configs/encrypted_old.yaml b/tests/data/configs/encrypted_old.yaml similarity index 100% rename from tests/features/configs/encrypted_old.yaml rename to tests/data/configs/encrypted_old.yaml diff --git a/tests/features/configs/format_md.yaml b/tests/data/configs/format_md.yaml similarity index 100% rename from tests/features/configs/format_md.yaml rename to tests/data/configs/format_md.yaml diff --git a/tests/features/configs/format_text.yaml b/tests/data/configs/format_text.yaml similarity index 100% rename from tests/features/configs/format_text.yaml rename to tests/data/configs/format_text.yaml diff --git a/tests/features/configs/invalid_color.yaml b/tests/data/configs/invalid_color.yaml similarity index 100% rename from tests/features/configs/invalid_color.yaml rename to tests/data/configs/invalid_color.yaml diff --git a/tests/features/configs/little_endian_dates.yaml b/tests/data/configs/little_endian_dates.yaml similarity index 100% rename from tests/features/configs/little_endian_dates.yaml rename to tests/data/configs/little_endian_dates.yaml diff --git a/tests/features/configs/markdown-headings-335.yaml b/tests/data/configs/markdown-headings-335.yaml similarity index 100% rename from tests/features/configs/markdown-headings-335.yaml rename to tests/data/configs/markdown-headings-335.yaml diff --git a/tests/features/configs/missing_directory.yaml b/tests/data/configs/missing_directory.yaml similarity index 100% rename from tests/features/configs/missing_directory.yaml rename to tests/data/configs/missing_directory.yaml diff --git a/tests/features/configs/missing_journal.yaml b/tests/data/configs/missing_journal.yaml similarity index 100% rename from tests/features/configs/missing_journal.yaml rename to tests/data/configs/missing_journal.yaml diff --git a/tests/features/configs/mostlyreadabledates.yaml b/tests/data/configs/mostlyreadabledates.yaml similarity index 100% rename from tests/features/configs/mostlyreadabledates.yaml rename to tests/data/configs/mostlyreadabledates.yaml diff --git a/tests/features/configs/multiline-tags.yaml b/tests/data/configs/multiline-tags.yaml similarity index 100% rename from tests/features/configs/multiline-tags.yaml rename to tests/data/configs/multiline-tags.yaml diff --git a/tests/features/configs/multiline.yaml b/tests/data/configs/multiline.yaml similarity index 100% rename from tests/features/configs/multiline.yaml rename to tests/data/configs/multiline.yaml diff --git a/tests/features/configs/multiple.yaml b/tests/data/configs/multiple.yaml similarity index 100% rename from tests/features/configs/multiple.yaml rename to tests/data/configs/multiple.yaml diff --git a/tests/features/configs/no_colors.yaml b/tests/data/configs/no_colors.yaml similarity index 100% rename from tests/features/configs/no_colors.yaml rename to tests/data/configs/no_colors.yaml diff --git a/tests/features/data/configs/simple.yaml b/tests/data/configs/simple.yaml similarity index 100% rename from tests/features/data/configs/simple.yaml rename to tests/data/configs/simple.yaml diff --git a/tests/features/configs/tags-216.yaml b/tests/data/configs/tags-216.yaml similarity index 100% rename from tests/features/configs/tags-216.yaml rename to tests/data/configs/tags-216.yaml diff --git a/tests/features/configs/tags-237.yaml b/tests/data/configs/tags-237.yaml similarity index 100% rename from tests/features/configs/tags-237.yaml rename to tests/data/configs/tags-237.yaml diff --git a/tests/features/configs/tags.yaml b/tests/data/configs/tags.yaml similarity index 100% rename from tests/features/configs/tags.yaml rename to tests/data/configs/tags.yaml diff --git a/tests/features/configs/unreadabledates.yaml b/tests/data/configs/unreadabledates.yaml similarity index 100% rename from tests/features/configs/unreadabledates.yaml rename to tests/data/configs/unreadabledates.yaml diff --git a/tests/features/configs/upgrade_from_195.json b/tests/data/configs/upgrade_from_195.json similarity index 100% rename from tests/features/configs/upgrade_from_195.json rename to tests/data/configs/upgrade_from_195.json diff --git a/tests/features/configs/upgrade_from_195_little_endian_dates.json b/tests/data/configs/upgrade_from_195_little_endian_dates.json similarity index 100% rename from tests/features/configs/upgrade_from_195_little_endian_dates.json rename to tests/data/configs/upgrade_from_195_little_endian_dates.json diff --git a/tests/features/configs/upgrade_from_195_with_missing_encrypted_journal.json b/tests/data/configs/upgrade_from_195_with_missing_encrypted_journal.json similarity index 100% rename from tests/features/configs/upgrade_from_195_with_missing_encrypted_journal.json rename to tests/data/configs/upgrade_from_195_with_missing_encrypted_journal.json diff --git a/tests/features/configs/upgrade_from_195_with_missing_journal.json b/tests/data/configs/upgrade_from_195_with_missing_journal.json similarity index 100% rename from tests/features/configs/upgrade_from_195_with_missing_journal.json rename to tests/data/configs/upgrade_from_195_with_missing_journal.json diff --git a/tests/features/data/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry b/tests/data/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry similarity index 100% rename from tests/features/data/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry rename to tests/data/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry diff --git a/tests/features/data/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry b/tests/data/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry similarity index 100% rename from tests/features/data/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry rename to tests/data/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry diff --git a/tests/features/data/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry b/tests/data/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry similarity index 100% rename from tests/features/data/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry rename to tests/data/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry diff --git a/tests/features/data/journals/basic_encrypted.journal b/tests/data/journals/basic_encrypted.journal similarity index 100% rename from tests/features/data/journals/basic_encrypted.journal rename to tests/data/journals/basic_encrypted.journal diff --git a/tests/features/data/journals/basic_folder/2020/08/29.txt b/tests/data/journals/basic_folder/2020/08/29.txt similarity index 100% rename from tests/features/data/journals/basic_folder/2020/08/29.txt rename to tests/data/journals/basic_folder/2020/08/29.txt diff --git a/tests/features/data/journals/basic_folder/2020/08/31.txt b/tests/data/journals/basic_folder/2020/08/31.txt similarity index 100% rename from tests/features/data/journals/basic_folder/2020/08/31.txt rename to tests/data/journals/basic_folder/2020/08/31.txt diff --git a/tests/features/data/journals/basic_folder/2020/09/24.txt b/tests/data/journals/basic_folder/2020/09/24.txt similarity index 100% rename from tests/features/data/journals/basic_folder/2020/09/24.txt rename to tests/data/journals/basic_folder/2020/09/24.txt diff --git a/tests/features/data/journals/basic_onefile.journal b/tests/data/journals/basic_onefile.journal similarity index 100% rename from tests/features/data/journals/basic_onefile.journal rename to tests/data/journals/basic_onefile.journal diff --git a/tests/features/data/journals/brackets.journal b/tests/data/journals/brackets.journal similarity index 100% rename from tests/features/data/journals/brackets.journal rename to tests/data/journals/brackets.journal diff --git a/tests/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry b/tests/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry similarity index 100% rename from tests/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry rename to tests/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry diff --git a/tests/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry b/tests/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry similarity index 100% rename from tests/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry rename to tests/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry diff --git a/tests/features/data/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry b/tests/data/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry similarity index 100% rename from tests/features/data/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry rename to tests/data/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry diff --git a/tests/features/data/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry b/tests/data/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry similarity index 100% rename from tests/features/data/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry rename to tests/data/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry diff --git a/tests/features/data/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry b/tests/data/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry similarity index 100% rename from tests/features/data/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry rename to tests/data/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry diff --git a/tests/features/data/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry b/tests/data/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry similarity index 100% rename from tests/features/data/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry rename to tests/data/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry diff --git a/tests/features/data/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry b/tests/data/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry similarity index 100% rename from tests/features/data/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry rename to tests/data/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry diff --git a/tests/features/data/journals/dayone_empty.dayone/entries/empty.txt b/tests/data/journals/dayone_empty.dayone/entries/empty.txt similarity index 100% rename from tests/features/data/journals/dayone_empty.dayone/entries/empty.txt rename to tests/data/journals/dayone_empty.dayone/entries/empty.txt diff --git a/tests/features/data/journals/deletion.journal b/tests/data/journals/deletion.journal similarity index 100% rename from tests/features/data/journals/deletion.journal rename to tests/data/journals/deletion.journal diff --git a/tests/features/data/journals/deletion_filters.journal b/tests/data/journals/deletion_filters.journal similarity index 100% rename from tests/features/data/journals/deletion_filters.journal rename to tests/data/journals/deletion_filters.journal diff --git a/tests/features/data/journals/empty_folder/empty b/tests/data/journals/empty_folder/empty similarity index 100% rename from tests/features/data/journals/empty_folder/empty rename to tests/data/journals/empty_folder/empty diff --git a/tests/features/data/journals/encrypted.journal b/tests/data/journals/encrypted.journal similarity index 100% rename from tests/features/data/journals/encrypted.journal rename to tests/data/journals/encrypted.journal diff --git a/tests/features/data/journals/encrypted_jrnl-1-9-5.journal b/tests/data/journals/encrypted_jrnl-1-9-5.journal similarity index 100% rename from tests/features/data/journals/encrypted_jrnl-1-9-5.journal rename to tests/data/journals/encrypted_jrnl-1-9-5.journal diff --git a/tests/features/data/journals/little_endian_dates.journal b/tests/data/journals/little_endian_dates.journal similarity index 100% rename from tests/features/data/journals/little_endian_dates.journal rename to tests/data/journals/little_endian_dates.journal diff --git a/tests/features/data/journals/markdown-headings-335.journal b/tests/data/journals/markdown-headings-335.journal similarity index 100% rename from tests/features/data/journals/markdown-headings-335.journal rename to tests/data/journals/markdown-headings-335.journal diff --git a/tests/features/data/journals/mostlyreadabledates.journal b/tests/data/journals/mostlyreadabledates.journal similarity index 100% rename from tests/features/data/journals/mostlyreadabledates.journal rename to tests/data/journals/mostlyreadabledates.journal diff --git a/tests/features/data/journals/multiline-tags.journal b/tests/data/journals/multiline-tags.journal similarity index 100% rename from tests/features/data/journals/multiline-tags.journal rename to tests/data/journals/multiline-tags.journal diff --git a/tests/features/data/journals/multiline.journal b/tests/data/journals/multiline.journal similarity index 100% rename from tests/features/data/journals/multiline.journal rename to tests/data/journals/multiline.journal diff --git a/tests/features/data/journals/simple.journal b/tests/data/journals/simple.journal similarity index 100% rename from tests/features/data/journals/simple.journal rename to tests/data/journals/simple.journal diff --git a/tests/features/data/journals/simple_jrnl-1-9-5.journal b/tests/data/journals/simple_jrnl-1-9-5.journal similarity index 100% rename from tests/features/data/journals/simple_jrnl-1-9-5.journal rename to tests/data/journals/simple_jrnl-1-9-5.journal diff --git a/tests/features/data/journals/simple_jrnl-1-9-5_little_endian_dates.journal b/tests/data/journals/simple_jrnl-1-9-5_little_endian_dates.journal similarity index 100% rename from tests/features/data/journals/simple_jrnl-1-9-5_little_endian_dates.journal rename to tests/data/journals/simple_jrnl-1-9-5_little_endian_dates.journal diff --git a/tests/features/data/journals/tags-216.journal b/tests/data/journals/tags-216.journal similarity index 100% rename from tests/features/data/journals/tags-216.journal rename to tests/data/journals/tags-216.journal diff --git a/tests/features/data/journals/tags-237.journal b/tests/data/journals/tags-237.journal similarity index 100% rename from tests/features/data/journals/tags-237.journal rename to tests/data/journals/tags-237.journal diff --git a/tests/features/data/journals/tags.journal b/tests/data/journals/tags.journal similarity index 100% rename from tests/features/data/journals/tags.journal rename to tests/data/journals/tags.journal diff --git a/tests/features/data/journals/unreadabledates.journal b/tests/data/journals/unreadabledates.journal similarity index 100% rename from tests/features/data/journals/unreadabledates.journal rename to tests/data/journals/unreadabledates.journal diff --git a/tests/features/data/journals/work.journal b/tests/data/journals/work.journal similarity index 100% rename from tests/features/data/journals/work.journal rename to tests/data/journals/work.journal diff --git a/tests/features/data/templates/sample.template b/tests/data/templates/sample.template similarity index 100% rename from tests/features/data/templates/sample.template rename to tests/data/templates/sample.template diff --git a/tests/features/configs/editor_markdown_extension.yaml b/tests/features/configs/editor_markdown_extension.yaml deleted file mode 100644 index bf3b8d8e..00000000 --- a/tests/features/configs/editor_markdown_extension.yaml +++ /dev/null @@ -1,18 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -editor: "vim" -journals: - default: features/journals/editor_markdown_extension.journal -linewrap: 80 -tagsymbols: "@" -template: features/templates/extension.md -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/tests/features/configs/simple.yaml b/tests/features/configs/simple.yaml deleted file mode 100644 index f8739142..00000000 --- a/tests/features/configs/simple.yaml +++ /dev/null @@ -1,18 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/simple.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none -version: v2.5 \ No newline at end of file diff --git a/tests/features/core.feature b/tests/features/core.feature index 3115fd57..67a73a12 100644 --- a/tests/features/core.feature +++ b/tests/features/core.feature @@ -5,3 +5,4 @@ Feature: Functionality of jrnl outside of actually handling journals When we run "jrnl --version" Then we should get no error Then the output should match "^jrnl version v\d+\.\d+(\.\d+)?(-(alpha|beta)\d*)?" + diff --git a/tests/features/data/configs/basic_dayone.yaml b/tests/features/data/configs/basic_dayone.yaml deleted file mode 100644 index 0209f2f7..00000000 --- a/tests/features/data/configs/basic_dayone.yaml +++ /dev/null @@ -1,17 +0,0 @@ -colors: - date: none - title: none - body: none - tags: none -default_hour: 9 -default_minute: 0 -editor: noop -encrypt: false -highlight: true -journals: - default: features/journals/basic_dayone.dayone -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/tests/features/data/configs/basic_encrypted.yaml b/tests/features/data/configs/basic_encrypted.yaml deleted file mode 100644 index 77f4e48d..00000000 --- a/tests/features/data/configs/basic_encrypted.yaml +++ /dev/null @@ -1,17 +0,0 @@ -colors: - date: none - title: none - body: none - tags: none -default_hour: 9 -default_minute: 0 -editor: noop -encrypt: true -highlight: true -journals: - default: features/journals/basic_encrypted.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/tests/features/data/configs/basic_folder.yaml b/tests/features/data/configs/basic_folder.yaml deleted file mode 100644 index ba0de638..00000000 --- a/tests/features/data/configs/basic_folder.yaml +++ /dev/null @@ -1,17 +0,0 @@ -colors: - date: none - title: none - body: none - tags: none -default_hour: 9 -default_minute: 0 -editor: noop -encrypt: false -highlight: true -journals: - default: features/journals/basic_folder -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/tests/features/data/configs/basic_onefile.yaml b/tests/features/data/configs/basic_onefile.yaml deleted file mode 100644 index fb48c6f8..00000000 --- a/tests/features/data/configs/basic_onefile.yaml +++ /dev/null @@ -1,17 +0,0 @@ -colors: - date: none - title: none - body: none - tags: none -default_hour: 9 -default_minute: 0 -editor: noop -encrypt: false -highlight: true -journals: - default: features/journals/basic_onefile.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/tests/features/data/configs/brackets.yaml b/tests/features/data/configs/brackets.yaml deleted file mode 100644 index e658947c..00000000 --- a/tests/features/data/configs/brackets.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/brackets.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/tests/features/data/configs/bug153.yaml b/tests/features/data/configs/bug153.yaml deleted file mode 100644 index ff645ab6..00000000 --- a/tests/features/data/configs/bug153.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: false -highlight: true -journals: - default: features/journals/bug153.dayone -linewrap: 80 -tagsymbols: '@' -template: false -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/tests/features/data/configs/bug343.yaml b/tests/features/data/configs/bug343.yaml deleted file mode 100644 index a4e25d8a..00000000 --- a/tests/features/data/configs/bug343.yaml +++ /dev/null @@ -1,13 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -template: false -encrypt: false -highlight: true -journals: - simple: features/journals/simple.journal - work: features/journals/work.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/tests/features/data/configs/bug780.yaml b/tests/features/data/configs/bug780.yaml deleted file mode 100644 index e1d830c2..00000000 --- a/tests/features/data/configs/bug780.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: false -highlight: true -journals: - default: features/journals/bug780.dayone -linewrap: 80 -tagsymbols: '@' -template: false -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/tests/features/data/configs/dayone.yaml b/tests/features/data/configs/dayone.yaml deleted file mode 100644 index 894cb911..00000000 --- a/tests/features/data/configs/dayone.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: noop -template: false -encrypt: false -highlight: true -journals: - default: features/journals/dayone.dayone -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/tests/features/data/configs/dayone_empty.yaml b/tests/features/data/configs/dayone_empty.yaml deleted file mode 100644 index 7750d389..00000000 --- a/tests/features/data/configs/dayone_empty.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: noop -template: false -encrypt: false -highlight: true -journals: - default: features/journals/dayone_empty.dayone -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/tests/features/data/configs/deletion.yaml b/tests/features/data/configs/deletion.yaml deleted file mode 100644 index d4155260..00000000 --- a/tests/features/data/configs/deletion.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/deletion.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/tests/features/data/configs/deletion_filters.yaml b/tests/features/data/configs/deletion_filters.yaml deleted file mode 100644 index 73a88e4d..00000000 --- a/tests/features/data/configs/deletion_filters.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/deletion_filters.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/tests/features/data/configs/editor-args.yaml b/tests/features/data/configs/editor-args.yaml deleted file mode 100644 index 12c5bd9c..00000000 --- a/tests/features/data/configs/editor-args.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: vim -f -c 'setf markdown' -encrypt: false -highlight: true -journals: - default: features/journals/simple.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/tests/features/data/configs/editor.yaml b/tests/features/data/configs/editor.yaml deleted file mode 100644 index 8a06f916..00000000 --- a/tests/features/data/configs/editor.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "vim" -encrypt: false -highlight: true -journals: - default: features/journals/simple.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/tests/features/data/configs/editor_empty_folder.yaml b/tests/features/data/configs/editor_empty_folder.yaml deleted file mode 100644 index 1724bbfb..00000000 --- a/tests/features/data/configs/editor_empty_folder.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: 'vim' -template: false -encrypt: false -highlight: true -journals: - default: features/journals/empty_folder -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/tests/features/data/configs/editor_encrypted.yaml b/tests/features/data/configs/editor_encrypted.yaml deleted file mode 100644 index 75273c96..00000000 --- a/tests/features/data/configs/editor_encrypted.yaml +++ /dev/null @@ -1,17 +0,0 @@ -colors: - body: green - date: blue - tags: none - title: yellow -default_hour: 9 -default_minute: 0 -editor: "vim" -encrypt: true -template: false -highlight: true -journals: - default: features/journals/encrypted.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/tests/features/data/configs/empty_folder.yaml b/tests/features/data/configs/empty_folder.yaml deleted file mode 100644 index 52a21854..00000000 --- a/tests/features/data/configs/empty_folder.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -template: false -encrypt: false -highlight: true -journals: - default: features/journals/empty_folder -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/tests/features/data/configs/encrypted.yaml b/tests/features/data/configs/encrypted.yaml deleted file mode 100644 index 4d50b607..00000000 --- a/tests/features/data/configs/encrypted.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: true -template: false -highlight: true -journals: - default: features/journals/encrypted.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/tests/features/data/configs/encrypted_old.json b/tests/features/data/configs/encrypted_old.json deleted file mode 100644 index e69d9b79..00000000 --- a/tests/features/data/configs/encrypted_old.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "default_hour": 9, - "default_minute": 0, - "editor": "", - "encrypt": true, - "highlight": true, - "journals": { - "default": "features/journals/encrypted_jrnl-1-9-5.journal" - }, - "linewrap": 80, - "tagsymbols": "@", - "timeformat": "%Y-%m-%d %H:%M" -} diff --git a/tests/features/data/configs/encrypted_old.yaml b/tests/features/data/configs/encrypted_old.yaml deleted file mode 100644 index bc7b1440..00000000 --- a/tests/features/data/configs/encrypted_old.yaml +++ /dev/null @@ -1,11 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: true -highlight: true -journals: - default: features/journals/encrypted_jrnl1-9-5.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/tests/features/data/configs/format_md.yaml b/tests/features/data/configs/format_md.yaml deleted file mode 100644 index 0b9f1c3b..00000000 --- a/tests/features/data/configs/format_md.yaml +++ /dev/null @@ -1,19 +0,0 @@ -colors: - body: none - date: none - tags: none - title: none -default_hour: 9 -default_minute: 0 -display_format: markdown -editor: '' -encrypt: false -highlight: true -indent_character: '|' -journals: - default: features/journals/simple.journal -linewrap: 80 -tagsymbols: '@' -template: false -timeformat: '%Y-%m-%d %H:%M' -version: v2.4.5 diff --git a/tests/features/data/configs/format_text.yaml b/tests/features/data/configs/format_text.yaml deleted file mode 100644 index c82ff7a7..00000000 --- a/tests/features/data/configs/format_text.yaml +++ /dev/null @@ -1,19 +0,0 @@ -colors: - body: none - date: none - tags: none - title: none -default_hour: 9 -default_minute: 0 -display_format: text -editor: '' -encrypt: false -highlight: true -indent_character: '|' -journals: - default: features/journals/simple.journal -linewrap: 80 -tagsymbols: '@' -template: false -timeformat: '%Y-%m-%d %H:%M' -version: v2.4.5 diff --git a/tests/features/data/configs/invalid_color.yaml b/tests/features/data/configs/invalid_color.yaml deleted file mode 100644 index 25c0e58d..00000000 --- a/tests/features/data/configs/invalid_color.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/simple.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" -colors: - date: not-a-color - title: also-not-a-color - body: still-no-color - tags: me-too diff --git a/tests/features/data/configs/little_endian_dates.yaml b/tests/features/data/configs/little_endian_dates.yaml deleted file mode 100644 index 223c820d..00000000 --- a/tests/features/data/configs/little_endian_dates.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/little_endian_dates.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%d.%m.%Y %H:%M" -indent_character: "|" diff --git a/tests/features/data/configs/markdown-headings-335.yaml b/tests/features/data/configs/markdown-headings-335.yaml deleted file mode 100644 index 4368f641..00000000 --- a/tests/features/data/configs/markdown-headings-335.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: false -highlight: true -template: false -journals: - default: features/journals/markdown-headings-335.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/tests/features/data/configs/missing_directory.yaml b/tests/features/data/configs/missing_directory.yaml deleted file mode 100644 index d600404c..00000000 --- a/tests/features/data/configs/missing_directory.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/missing_directory/simple.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/tests/features/data/configs/missing_journal.yaml b/tests/features/data/configs/missing_journal.yaml deleted file mode 100644 index a1f6f8cf..00000000 --- a/tests/features/data/configs/missing_journal.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/missing.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/tests/features/data/configs/mostlyreadabledates.yaml b/tests/features/data/configs/mostlyreadabledates.yaml deleted file mode 100644 index 5e3e1a15..00000000 --- a/tests/features/data/configs/mostlyreadabledates.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/mostlyreadabledates.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/tests/features/data/configs/multiline-tags.yaml b/tests/features/data/configs/multiline-tags.yaml deleted file mode 100644 index 033aaa27..00000000 --- a/tests/features/data/configs/multiline-tags.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/multiline-tags.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/tests/features/data/configs/multiline.yaml b/tests/features/data/configs/multiline.yaml deleted file mode 100644 index aa35b3f5..00000000 --- a/tests/features/data/configs/multiline.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/multiline.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/tests/features/data/configs/multiple.yaml b/tests/features/data/configs/multiple.yaml deleted file mode 100644 index 65f2c256..00000000 --- a/tests/features/data/configs/multiple.yaml +++ /dev/null @@ -1,18 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: false -highlight: true -template: false -journals: - default: features/journals/simple.journal - ideas: features/journals/nothing.journal - simple: features/journals/simple.journal - work: features/journals/work.journal - new_encrypted: - encrypt: true - journal: features/journals/new_encrypted.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/tests/features/data/configs/no_colors.yaml b/tests/features/data/configs/no_colors.yaml deleted file mode 100644 index 9111b561..00000000 --- a/tests/features/data/configs/no_colors.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/simple.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/tests/features/data/configs/tags-216.yaml b/tests/features/data/configs/tags-216.yaml deleted file mode 100644 index 81b3865f..00000000 --- a/tests/features/data/configs/tags-216.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: false -highlight: true -template: false -journals: - default: features/journals/tags-216.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/tests/features/data/configs/tags-237.yaml b/tests/features/data/configs/tags-237.yaml deleted file mode 100644 index 5aecd61e..00000000 --- a/tests/features/data/configs/tags-237.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: false -highlight: true -template: false -journals: - default: features/journals/tags-237.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/tests/features/data/configs/tags.yaml b/tests/features/data/configs/tags.yaml deleted file mode 100644 index 4b55952c..00000000 --- a/tests/features/data/configs/tags.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: false -highlight: true -template: false -journals: - default: features/journals/tags.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/tests/features/data/configs/unreadabledates.yaml b/tests/features/data/configs/unreadabledates.yaml deleted file mode 100644 index 99304e5a..00000000 --- a/tests/features/data/configs/unreadabledates.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/unreadabledates.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/tests/features/data/configs/upgrade_from_195.json b/tests/features/data/configs/upgrade_from_195.json deleted file mode 100644 index ec380372..00000000 --- a/tests/features/data/configs/upgrade_from_195.json +++ /dev/null @@ -1,11 +0,0 @@ -{ -"default_hour": 9, -"timeformat": "%Y-%m-%d %H:%M", -"linewrap": 80, -"encrypt": false, -"editor": "", -"default_minute": 0, -"highlight": true, -"journals": {"default": "features/journals/simple_jrnl-1-9-5.journal"}, -"tagsymbols": "@" -} diff --git a/tests/features/data/configs/upgrade_from_195_little_endian_dates.json b/tests/features/data/configs/upgrade_from_195_little_endian_dates.json deleted file mode 100644 index 7d3c470c..00000000 --- a/tests/features/data/configs/upgrade_from_195_little_endian_dates.json +++ /dev/null @@ -1,11 +0,0 @@ -{ -"default_hour": 9, -"timeformat": "%d.%m.%Y %H:%M", -"linewrap": 80, -"encrypt": false, -"editor": "", -"default_minute": 0, -"highlight": true, -"journals": {"default": "features/journals/simple_jrnl-1-9-5_little_endian_dates.journal"}, -"tagsymbols": "@" -} diff --git a/tests/features/data/configs/upgrade_from_195_with_missing_encrypted_journal.json b/tests/features/data/configs/upgrade_from_195_with_missing_encrypted_journal.json deleted file mode 100644 index 5bbfb5b1..00000000 --- a/tests/features/data/configs/upgrade_from_195_with_missing_encrypted_journal.json +++ /dev/null @@ -1,11 +0,0 @@ -{ -"default_hour": 9, -"timeformat": "%Y-%m-%d %H:%M", -"linewrap": 80, -"encrypt": true, -"editor": "", -"default_minute": 0, -"highlight": true, -"journals": {"default": "features/journals/encrypted_jrnl-1-9-5.journal", "missing": "features/journals/missing.journal"}, -"tagsymbols": "@" -} diff --git a/tests/features/data/configs/upgrade_from_195_with_missing_journal.json b/tests/features/data/configs/upgrade_from_195_with_missing_journal.json deleted file mode 100644 index 8d456159..00000000 --- a/tests/features/data/configs/upgrade_from_195_with_missing_journal.json +++ /dev/null @@ -1,11 +0,0 @@ -{ -"default_hour": 9, -"timeformat": "%Y-%m-%d %H:%M", -"linewrap": 80, -"encrypt": false, -"editor": "", -"default_minute": 0, -"highlight": true, -"journals": {"default": "features/journals/simple_jrnl-1-9-5.journal", "missing": "features/journals/missing.journal"}, -"tagsymbols": "@" -} diff --git a/tests/features/environment.py b/tests/features/environment.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/features/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry b/tests/features/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry deleted file mode 100644 index 9721dd55..00000000 --- a/tests/features/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry +++ /dev/null @@ -1,53 +0,0 @@ - - - - - Creation Date - 2020-08-29T18:11:00Z - Starred - - Entry Text - Entry the first. -Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada -quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque -augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu -consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In -commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget -venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. - -Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo -ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse -potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget -molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus -hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis -feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum -urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget -velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac -porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per -conubia nostra, per inceptos himenaeos. - Time Zone - America/Los_Angeles - UUID - D04D335AFED711EABA18FAFFC2100C3D - Tags - - ipsum - tagone - tagtwo - - Creator - - Device Agent - - Generation Date - 2020-09-25T02:35:45Z - Host Name - iris.lan - OS Agent - Darwin/19.3.0 - Software Agent - jrnl/v2.4.5 - - - diff --git a/tests/features/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry b/tests/features/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry deleted file mode 100644 index 8c2f3c52..00000000 --- a/tests/features/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry +++ /dev/null @@ -1,55 +0,0 @@ - - - - - Creation Date - 2020-08-31T21:32:00Z - Starred - - Entry Text - A second entry in what I hope to be a long series. -Sed sit amet metus et sapien feugiat elementum. Aliquam bibendum lobortis leo -vitae tempus. Donec eleifend nec mi non volutpat. Lorem ipsum dolor sit amet, -consectetur adipiscing elit. Praesent ut sodales libero. Maecenas nisl lorem, -vestibulum in tempus sit amet, fermentum ut arcu. Donec vel vestibulum lectus, -eget pretium enim. Maecenas diam nunc, imperdiet vitae pharetra sed, pretium id -lectus. Donec eu metus et turpis tempor tristique ac non ex. In tellus arcu, -egestas at efficitur et, ultrices vel est. Sed commodo et nibh non elementum. -Mauris tempus vitae neque vel viverra. @tagtwo all by its lonesome. - -Nulla mattis elementum magna, viverra pretium dui fermentum et. Cras vel -vestibulum odio. Quisque sit amet turpis et urna finibus maximus. Interdum et -malesuada fames ac ante ipsum primis in faucibus. Fusce porttitor iaculis sem, -non dictum ipsum varius nec. Nulla eu erat at risus gravida blandit non vel -ante. Nam egestas ipsum leo, eu ultricies ipsum tincidunt vel. Morbi a commodo -eros. - -Nullam dictum, nisl ac varius tempus, ex tortor fermentum nisl, non -tempus dolor neque a lorem. Suspendisse a faucibus ex, vel ornare tortor. -Maecenas tincidunt id felis quis semper. Pellentesque enim libero, fermentum -quis metus id, rhoncus euismod magna. Nulla finibus velit eu purus bibendum -interdum. Integer id justo dui. Integer eu tellus in turpis bibendum blandit. -Quisque auctor lacinia consectetur. - Time Zone - America/Los_Angeles - UUID - FC8A86CAFED711EA8892FAFFC2100C3D - Tags - - tagtwo - - Creator - - Device Agent - - Generation Date - 2020-09-25T02:36:59Z - Host Name - iris.lan - OS Agent - Darwin/19.3.0 - Software Agent - jrnl/v2.4.5 - - - diff --git a/tests/features/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry b/tests/features/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry deleted file mode 100644 index d998c36b..00000000 --- a/tests/features/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry +++ /dev/null @@ -1,44 +0,0 @@ - - - - - Creation Date - 2020-09-24T16:14:00Z - Starred - - Entry Text - The third entry finally after weeks without writing. -I'm so excited about emojis. 💯 🎶 💩 - -Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. -Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla -eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis -dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. -Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis -vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. -Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at -ante eget fringilla. @tagthree and also @tagone - Time Zone - America/Los_Angeles - UUID - FD8ABC8EFED711EABC35FAFFC2100C3D - Tags - - tagthree - tagone - - Creator - - Device Agent - - Generation Date - 2020-09-25T02:37:01Z - Host Name - iris.lan - OS Agent - Darwin/19.3.0 - Software Agent - jrnl/v2.4.5 - - - diff --git a/tests/features/journals/basic_encrypted.journal b/tests/features/journals/basic_encrypted.journal deleted file mode 100644 index ffc122df..00000000 --- a/tests/features/journals/basic_encrypted.journal +++ /dev/null @@ -1 +0,0 @@ -gAAAAABfb4gQBMqqGn_W8v_s7qCi14bX7inuCOKbsBqIUf7_ch14vTUp7lrysPFvhBp5vGijTwDIbk4LKoIISj8NwM31I8L0zEbMx9y6iyF_zseGGNxBvNN0wzAXa67bs-ohiQhhebcdIc_52sltxL2ELh8JAKUaXRwyapgnMgJ7z6deJppLK-B7RE7BiT0eKjWTDMd2x6cZDswvHs9opDp5yjuKWV5m7x6ggCKYgHT3savT9Tg7V0Fq6K3LGWaE59lCrqlAB0u6dnrDX3qcF4SKyckaniXzRShZGebdkUKDcLFun2V2syZwYQN772xjznIsJ16iXicox2uYKg8CnTefsyCwaOZyBvySGEy3CrlBiuIRIcxCtjKbYJ2B-Aq7LZitnBR7Ny_6_Wm8HsBf3N-cFCp4GShiCKrxuXKcOZ7vszG5EKb78JS85bb0mswU5CSdgp6UAHjIZqfJq00qQsViBCbXq3oklCPZXdQkOf5U0KpG2MVUiD-Zcn5Qj3gnUhSEr-5wKU9tWrE63MGPyE6KjZlArZX2W2LeGnW2CEYw9eREGon06AzLJ4mj3BgtjVWLIdGcCwORXvHRjUqazWgbEmXNVTbtp_cKnkW-rFzRBrUoVme9v-1Y3sH0VvHBq7QIj915VzBklzWs1qzIyTPZG5Db9LvdQ7SiV8slf1Jo7l-ayUUdVj6igvKZcgfB4RUHolJoMps5p4lZ5sPqv59KtSa8DCpuoRczIj71OCpuRVARZgy1m5sUD9xSMxOBdy46u1Jnry6iMtzXWI3mEZe5m7UhmW_L4Zcv4bbk8XjkBeHjPdgm2B69jkLmCBFecD5ztoGesCGt_pNo_sWSKqLHV1-coKFB2Nn__a4utU9NJNdeNRkr8_ahU6tn3jmaFjfQ7cKfrXG_NCcYBRX9fja8EQIeBEp_3TCoXQqhuV_bGsNPA2qL63Pt6YiRaUf1g9FNBqJRlKCSOYNixSXQZN_rTePzx0SQ0aIQhADWls62WX-LG5-byJcB6W2P_cH21hDOXkoNEIyLnCz9HQ6Yd6Fbv7298ps3F6jiUDdWES23zv8sDgBuKUN94qSN34j6MDYGFnGI9zsJ-Y-I2frdlLfWPx3pUL7afcKh1nRgXdjctsTSxU2BDrsu03eBz2IoZjoOR0U51IrNMOD1NNT3kctXxHLuOHSEkwAzS3doncQbdRLi5Gc1dQuOUa4sC-p8gVjUKXO-oi_49kp9Km2Ay9wFg0epBbXx2QMzyMsN2dXeSbHF-BDXD6sULaq5syC0fOHqaMLycTCMk2wLfNyXgEt05WvAiDn-LDsRdylMRW2hXp5HWq3Poaul-7VNg6UEMlwVfgJ-7hNreuO6IRtwmx6YdqMscw0ms6mU_MQZU_dTIPg3JU4KL0YyMqPBPSGNCx3gMp41O05Ubir45FoJSnT5Dkj4v3N0S87Ys3HuFLverASsGt9bkcSzd2uMKCJjkspemPPi9VhrY4IOO03DWSWbHmxYzFc1SJ-24WM8Ch404QKpe1qy5LNzFgLvDwQhSIHjluezHXqrD-DVh1lWNNY3WmHI2ubOZfaorvLKqzBPZ6AhpIa60rKjm0OZIQOmJwWXwkdnzut6m8PtoiLzRN897YMgeztf1nmDwp0xE-EhknVZ3WV3TeqgZJ5ykfHQ5BU8x0Db57-UtKSuesKbqPPdBe91OdsPpkGlyl6psHj1_gPm4nLvzXQePwiPaEemR_gYCWGPvl9l1ANJufgCV9qQTmZGof3fb9mjv-9lS-9l_m8KirPPRpSBToNeDtk50ceYUsOlDGzIyusppG9pOcIGyiln1IO5aZ8d4_1E83qjcHTSaKGizICZU7a-pt5STBPMesy3JgBm23A2jO4m68ayBRMcLnw_RirHvvBaj0C6UR2tac45F0Ob3PpXcvFuK0g54ziIAhzGqwF9I-LZ6asXQWMW4y4EBOak8JJBorkfztzfkMaIgGu-4ZoRKOkVfdr4uzcghk3r6KUxD4-nv1ioX69-G5RwhMHppYk7z8RXS1cq5FkvzXbfEQ-Uv6M-sx32DcUy9dH-ZYhc7UWm75JJfiNXLaXT_bsc6VqQ7KPkg2-RA7CywUFCW9S0S-XdO03VdwqlUVo7fp1SKywEfhZv_9bhDCdMJBwZmigv2KP9Iz7fF6LrpLwZkzHuQGFPcyTHFpsVIFrFyJjNYCXpET9y0Q5Vt4fnea5fy-9ZiCt3S8aS0YOFJ35_kM5i3ss8eFPL0v7fIQS3ZilzdGB3bWL0J7kppHN_ekHu-wVk3UZxauoFh7hXLjPcipua-FYUIklLjcK6DG1bYP7_q6OnkC8Jl650FNezeWPomHEv7l_DO3y0tjI6SGdWvL3ZJns7Xp3ew8KsCREAUO7ffqumD03uF9N-9uWbDDjM7rk0vcg0ggfOs9Ni725mxqYpu4R285XCOVWHDvw7iU6eAvE6ry8TDXQBbNgGjTuTYFYYli7GuOqMxFIe1op2s7sRnoJE8O0J76S6APhjhjcnZRSuONWkVG_5o83uFMPSF8DtqLwuRA5E8AGfIwAUcj324sw-DA0ixBGUqomb-osUIisv3x0b044xn-FvD-8R3PZDnPbPsao8XYNxfQWStrNcZSrX2Ua-WAcv9qbQ73_57RKW4pao4ajOu7K5800D231WGiIa6aJzDnFUlzXEzYxFQyx7qegkm_9rrEp_v8TC9mfAcjWX5DMrCkxUskx9YKDfpFYq4NuxO_414gReKzd-lmorfigvttgS10N1XD74SwFluXJv-bqTbI5-SuYAhDGMv1dqrn38i3rOMQqqnQomvaUJRprqxUsKz14sSE1Y-cNqq1FXzZ6vIJq-K3YTfFWPRLeqi6gHzqS_R2YBXXUduKuYgmakiVdP3bWc-Ca8WKh5sVi6P51MO-cS7i9AZWOaOz7F8PsB4JZxAJjSOr3NBmv3EEve9auTFCudRjfC6668I_NMHaTP5CCV4cuhuAxUuKUGgd6WFjDcvoYPyn_lu3bQiqD9MEag4CaJYI9PlraRv5mbqptwxv3pca7usd0GmXN_2No_nwxB4gVb48LsBBkH35njCa5iv2EKXUSOf0k3swaTSEahqbyI4EDzPXtU5uBO39iQzNpgfV_sUpnGdysjqueUVcdWGI_s5CnrNJ-_yDAY06AoXfLrjP8_3NXB2058xZ2rfmTNJNCULz9634dICJReXNnmplxIg3i6GbzFvjfNtqjrWr_iqBShyIwuOUJRbXzdJNggx2BDNG-PEWDXl89SaudFICkDvyZKEcATIss6ZXfULIMfCrqmWmFwgXfNEd9TuvjqoxFlLSaY4UfDMiYa_arUMblFfoo5nV07GANhUoQd-6HRe7LjYeX5VRodOx6ZmZjIAUq-DYr-hatJJFR2tjT_qZht2MJeYT3GZ3o54m8zBBt0JTN7HVpKaOaM3A2hEM_Ah0QZ-DkLDxtCzMuv987GDiLT2-Riya97a47yHIJhZFzFpflW2FcuC8RFWXlfUKTQfZkFmxh3MUekUuS4yu4Z121xojVswk_4P7-FqLaSnGT2epI69I_cvalRx3wjds9-5TFYqf4GridlFBRx6Fv2fpNB9Zvp9k7NQ9oYcPuXGLoXH5kmWBagPhEGKHA_pjFUZmCuwUIoeP4nP8lhFrX8OGezsbSBG773CRJzEdfcgAc5G-p6M_24WZLZHDrsVBAvgrNt6R9eQbEviWU28t_417QCp-or9qqt4OTKv1dp_4MlZh8YBg2-dtpvzSc1l5e4kQFJu7oWlpbgsjB6pl1oRRKp1maedX-gOAf559zC4l85gfEpPln9Cnl6xvERQzfO0Ey4q91SdsgK7i7FBrKKmi2wGiemFvnaQsrjZ_IFujLo8-2c8g9zTiyH1knyoVOAAnQxqGpsz6z6PNfSxr3_G8tOlNFTV-yqN_LdVHMgXtXjn3U9koGsfMulyUcBDdR3d_0Yn6iEjBt77tbxKi2ry-0gQrB1fdGsgKjyE_tMrW8D_lQz0IXsVOzd2ixsFVXMFzD6OOD8JldV0FbA-VDAS-Tp_ezIZVp6lRq54XBgvsjzDyOmOgDbSOQN6SQmvxPnIsml1wgmtm80z-9gHBqmimHBtLKB6L7CtLmmPICMS2pX3eWOmakxscxqs8AVjijJdz_NYNfcdBeDj_fhm6dqD6iwk3EBZZfsrmMGdXtAMqf1r9ng9tsz-FriXwQiJ3IM3loBsk5DKr9CcaJtKSPuwDDlRynD2vwcD-XyF6YTQdSJa9fEcq-qXya2Scj4mqQ4RDemJgErdradRfwJfII3fWHh18XxmYVqi9Bwn3YRgwEadyo0-HjbNq6vJXi12igmP99ciRAfMVQLjfUfTwoOHj44Y2Ru_hPjJcvB6FIn6KLrrCSrZnrshFdFn4L36z1CrS8fbtdvrG3kdZQxsUJnMqttuwKRpLnDWTWkIwj_GRBFrzCFgbwGp1XYhemxggyKVuhZPfyyTIM9rhlPth6eGyrpYfap24Av_mGPRBLnzcjtpGbACGdKQL034kVmI7yENGvmY40KSrWsVG_BE9bSJhx0EptFsT2IxnxbuFD4hGb4fFag9V0BDiKpUoOZqIVqVO8cAp-5w4twvWZKkrhu16JNlLoXWMoFANrw-tp5LKSin1CUeRa4LWVI1GR8tRkIad_GnCHRv9JEMswlNy9wi2sDNsSxWT7WNasUW5-glgK9pR7d2pXGGOWfHj1U6CKIqmAiO3iw8igzhvyx_dAxMxPo \ No newline at end of file diff --git a/tests/features/journals/basic_folder/2020/08/29.txt b/tests/features/journals/basic_folder/2020/08/29.txt deleted file mode 100644 index c8af54ca..00000000 --- a/tests/features/journals/basic_folder/2020/08/29.txt +++ /dev/null @@ -1,19 +0,0 @@ -[2020-08-29 11:11:00 AM] Entry the first. -Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada -quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque -augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu -consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In -commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget -venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. - -Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo -ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse -potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget -molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus -hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis -feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum -urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget -velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac -porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per -conubia nostra, per inceptos himenaeos. diff --git a/tests/features/journals/basic_folder/2020/08/31.txt b/tests/features/journals/basic_folder/2020/08/31.txt deleted file mode 100644 index 826e7cdb..00000000 --- a/tests/features/journals/basic_folder/2020/08/31.txt +++ /dev/null @@ -1,23 +0,0 @@ -[2020-08-31 02:32:00 PM] A second entry in what I hope to be a long series. * -Sed sit amet metus et sapien feugiat elementum. Aliquam bibendum lobortis leo -vitae tempus. Donec eleifend nec mi non volutpat. Lorem ipsum dolor sit amet, -consectetur adipiscing elit. Praesent ut sodales libero. Maecenas nisl lorem, -vestibulum in tempus sit amet, fermentum ut arcu. Donec vel vestibulum lectus, -eget pretium enim. Maecenas diam nunc, imperdiet vitae pharetra sed, pretium id -lectus. Donec eu metus et turpis tempor tristique ac non ex. In tellus arcu, -egestas at efficitur et, ultrices vel est. Sed commodo et nibh non elementum. -Mauris tempus vitae neque vel viverra. @tagtwo all by its lonesome. - -Nulla mattis elementum magna, viverra pretium dui fermentum et. Cras vel -vestibulum odio. Quisque sit amet turpis et urna finibus maximus. Interdum et -malesuada fames ac ante ipsum primis in faucibus. Fusce porttitor iaculis sem, -non dictum ipsum varius nec. Nulla eu erat at risus gravida blandit non vel -ante. Nam egestas ipsum leo, eu ultricies ipsum tincidunt vel. Morbi a commodo -eros. - -Nullam dictum, nisl ac varius tempus, ex tortor fermentum nisl, non -tempus dolor neque a lorem. Suspendisse a faucibus ex, vel ornare tortor. -Maecenas tincidunt id felis quis semper. Pellentesque enim libero, fermentum -quis metus id, rhoncus euismod magna. Nulla finibus velit eu purus bibendum -interdum. Integer id justo dui. Integer eu tellus in turpis bibendum blandit. -Quisque auctor lacinia consectetur. diff --git a/tests/features/journals/basic_folder/2020/09/24.txt b/tests/features/journals/basic_folder/2020/09/24.txt deleted file mode 100644 index 2bd885ce..00000000 --- a/tests/features/journals/basic_folder/2020/09/24.txt +++ /dev/null @@ -1,11 +0,0 @@ -[2020-09-24 09:14:00 AM] The third entry finally after weeks without writing. -I'm so excited about emojis. 💯 🎶 💩 - -Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. -Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla -eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis -dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. -Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis -vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. -Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at -ante eget fringilla. @tagthree and also @tagone diff --git a/tests/features/journals/basic_onefile.journal b/tests/features/journals/basic_onefile.journal deleted file mode 100644 index 0d988049..00000000 --- a/tests/features/journals/basic_onefile.journal +++ /dev/null @@ -1,58 +0,0 @@ -[2020-08-29 11:11] Entry the first. - -Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada -quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque -augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu -consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In -commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget -venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. - -Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo -ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse -potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget -molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus -hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis -feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum -urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget -velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac -porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per -conubia nostra, per inceptos himenaeos. - -[2020-08-31 14:32] A second entry in what I hope to be a long series. * - -Sed sit amet metus et sapien feugiat elementum. Aliquam bibendum lobortis leo -vitae tempus. Donec eleifend nec mi non volutpat. Lorem ipsum dolor sit amet, -consectetur adipiscing elit. Praesent ut sodales libero. Maecenas nisl lorem, -vestibulum in tempus sit amet, fermentum ut arcu. Donec vel vestibulum lectus, -eget pretium enim. Maecenas diam nunc, imperdiet vitae pharetra sed, pretium id -lectus. Donec eu metus et turpis tempor tristique ac non ex. In tellus arcu, -egestas at efficitur et, ultrices vel est. Sed commodo et nibh non elementum. -Mauris tempus vitae neque vel viverra. @tagtwo all by its lonesome. - -Nulla mattis elementum magna, viverra pretium dui fermentum et. Cras vel -vestibulum odio. Quisque sit amet turpis et urna finibus maximus. Interdum et -malesuada fames ac ante ipsum primis in faucibus. Fusce porttitor iaculis sem, -non dictum ipsum varius nec. Nulla eu erat at risus gravida blandit non vel -ante. Nam egestas ipsum leo, eu ultricies ipsum tincidunt vel. Morbi a commodo -eros. - -Nullam dictum, nisl ac varius tempus, ex tortor fermentum nisl, non -tempus dolor neque a lorem. Suspendisse a faucibus ex, vel ornare tortor. -Maecenas tincidunt id felis quis semper. Pellentesque enim libero, fermentum -quis metus id, rhoncus euismod magna. Nulla finibus velit eu purus bibendum -interdum. Integer id justo dui. Integer eu tellus in turpis bibendum blandit. -Quisque auctor lacinia consectetur. - -[2020-09-24 09:14] The third entry finally after weeks without writing. - -I'm so excited about emojis. 💯 🎶 💩 - -Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. -Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla -eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis -dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. -Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis -vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. -Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at -ante eget fringilla. @tagthree and also @tagone diff --git a/tests/features/journals/brackets.journal b/tests/features/journals/brackets.journal deleted file mode 100644 index 4649ea3e..00000000 --- a/tests/features/journals/brackets.journal +++ /dev/null @@ -1,2 +0,0 @@ -[2019-07-08 05:42] Entry subject -[1] line starting with 1 diff --git a/tests/features/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry b/tests/features/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry deleted file mode 100644 index 066821bb..00000000 --- a/tests/features/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry +++ /dev/null @@ -1,56 +0,0 @@ - - - - - Creation Date - 2013-10-27T02:27:27Z - Creator - - Device Agent - iPhone/iPhone3,1 - Generation Date - 2013-10-27T07:02:27Z - Host Name - omrt104001 - OS Agent - iOS/7.0.3 - Software Agent - Day One (iOS)/1.11.4 - - Entry Text - Some text. - Location - - Administrative Area - Östergötlands län - Country - Sverige - Latitude - 58.383400000000000 - Locality - City - Longitude - 15.577170000000000 - Place Name - Street - - Starred - - Time Zone - Europe/Stockholm - UUID - B40EE704E15846DE8D45C44118A4D511 - Weather - - Celsius - 12 - Description - Clear - Fahrenheit - 54 - IconName - sunnyn.png - - - diff --git a/tests/features/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry b/tests/features/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry deleted file mode 100644 index ea3efec5..00000000 --- a/tests/features/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry +++ /dev/null @@ -1,52 +0,0 @@ - - Creation Date - 2013-10-27T02:27:27Z - Creator - - Device Agent - iPhone/iPhone3,1 - Generation Date - 2013-10-27T07:02:27Z - Host Name - omrt104001 - OS Agent - iOS/7.0.3 - Software Agent - Day One (iOS)/1.11.4 - - Entry Text - This is not a valid plist. - Location - - Administrative Area - Östergötlands län - Country - Sverige - Latitude - 58.383400000000000 - Locality - City - Longitude - 15.577170000000000 - Place Name - Street - - Starred - - Time Zone - Europe/Stockholm - UUID - B40EE704E15846DE8D45C44118A4D511 - Weather - - Celsius - 12 - Description - Clear - Fahrenheit - 54 - IconName - sunnyn.png - - - diff --git a/tests/features/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry b/tests/features/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry deleted file mode 100644 index 426f1ea8..00000000 --- a/tests/features/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry +++ /dev/null @@ -1,33 +0,0 @@ - - - - - Activity - Stationary - Creation Date - 2019-12-30T21:28:54Z - Entry Text - - Starred - - UUID - 48A25033B34047C591160A4480197D8B - Creator - - Device Agent - PC - Generation Date - 2019-12-30T21:28:54Z - Host Name - LE-TREPORT - OS Agent - Microsoft Windows/10 Home - Software Agent - Journaley/2.1 - - Tags - - i_have_no_body - - - diff --git a/tests/features/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry b/tests/features/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry deleted file mode 100644 index 1ac26242..00000000 --- a/tests/features/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry +++ /dev/null @@ -1,34 +0,0 @@ - - - - - Creation Date - 2013-05-17T18:39:20Z - Creator - - Device Agent - Macintosh/MacBookAir5,2 - Generation Date - 2013-08-17T18:39:20Z - Host Name - Egeria - OS Agent - Mac OS X/10.8.4 - Software Agent - Day One (Mac)/1.8 - - Entry Text - This entry has tags! - Starred - - Tags - - work - PLaY - - Time Zone - America/Los_Angeles - UUID - 044F3747A38546168B572C2E3F217FA2 - - diff --git a/tests/features/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry b/tests/features/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry deleted file mode 100644 index 927de884..00000000 --- a/tests/features/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry +++ /dev/null @@ -1,46 +0,0 @@ - - - - - Creation Date - 2013-06-17T18:38:29Z - Creator - - Device Agent - Macintosh/MacBookAir5,2 - Generation Date - 2013-08-17T18:38:29Z - Host Name - Egeria - OS Agent - Mac OS X/10.8.4 - Software Agent - Day One (Mac)/1.8 - - Entry Text - This entry has a location. - Location - - Administrative Area - California - Country - Germany - Latitude - 52.4979764 - Locality - Berlin - Longitude - 13.2404758 - Place Name - Abandoned Spy Tower - - Starred - - Tags - - Time Zone - Europe/Berlin - UUID - 0BDDD6CDA43C4A9AA2681517CC35AD9D - - diff --git a/tests/features/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry b/tests/features/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry deleted file mode 100644 index 16260763..00000000 --- a/tests/features/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry +++ /dev/null @@ -1,31 +0,0 @@ - - - - - Creation Date - 2013-07-17T18:38:08Z - Creator - - Device Agent - Macintosh/MacBookAir5,2 - Generation Date - 2013-08-17T18:38:08Z - Host Name - Egeria - OS Agent - Mac OS X/10.8.4 - Software Agent - Day One (Mac)/1.8 - - Entry Text - This entry is starred! - Starred - - Tags - - Time Zone - America/Los_Angeles - UUID - 422BC895507944A291E6FC44FC6B8BFC - - diff --git a/tests/features/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry b/tests/features/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry deleted file mode 100644 index 9ebaf538..00000000 --- a/tests/features/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry +++ /dev/null @@ -1,29 +0,0 @@ - - - - - Creation Date - 2013-01-17T18:37:50Z - Creator - - Device Agent - Macintosh/MacBookAir5,2 - Generation Date - 2013-08-17T18:37:50Z - Host Name - Egeria - OS Agent - Mac OS X/10.8.4 - Software Agent - Day One (Mac)/1.8 - - Entry Text - This is a DayOne entry without Timezone. - Starred - - Tags - - UUID - 4BB1F46946AD439996C9B59DE7C4DDC1 - - diff --git a/tests/features/journals/dayone_empty.dayone/entries/empty.txt b/tests/features/journals/dayone_empty.dayone/entries/empty.txt deleted file mode 100644 index c86b8f66..00000000 --- a/tests/features/journals/dayone_empty.dayone/entries/empty.txt +++ /dev/null @@ -1 +0,0 @@ -This file exists to preserve the directory structure, but should be ignored by jrnl. diff --git a/tests/features/journals/deletion.journal b/tests/features/journals/deletion.journal deleted file mode 100644 index c0fa689d..00000000 --- a/tests/features/journals/deletion.journal +++ /dev/null @@ -1,5 +0,0 @@ -[2019-10-29 11:11] First entry. - -[2019-10-29 11:11] Second entry. - -[2019-10-29 11:13] Third entry. \ No newline at end of file diff --git a/tests/features/journals/deletion_filters.journal b/tests/features/journals/deletion_filters.journal deleted file mode 100644 index 9a3747db..00000000 --- a/tests/features/journals/deletion_filters.journal +++ /dev/null @@ -1,14 +0,0 @@ -[2019-10-01 08:00] It's just another day in October. -Not much to write about. - -[2020-01-01 08:00] Happy New Year! -So this is the New Year. @holidays - -[2020-03-01 08:00] It's just another day in March. -A stick, a stone, it's the end of the road. - -[2020-05-01 09:00] Happy May Day! -@holidays @springtime Several holidays fall on this date. - -[2020-05-02 12:10] Writing tests. * -@springtime They will help prevent bugs. diff --git a/tests/features/journals/empty_folder/empty b/tests/features/journals/empty_folder/empty deleted file mode 100644 index 175b82b5..00000000 --- a/tests/features/journals/empty_folder/empty +++ /dev/null @@ -1 +0,0 @@ -Nothing to see here diff --git a/tests/features/journals/encrypted.journal b/tests/features/journals/encrypted.journal deleted file mode 100644 index d2a5fcbe..00000000 --- a/tests/features/journals/encrypted.journal +++ /dev/null @@ -1 +0,0 @@ -gAAAAABVIHB7tnwKExG7aC5ZbAbBL9SG2oY2GENeoOJ22i1PZigOvCYvrQN3kpsu0KGr7ay5K-_46R5YFlqJvtQ8anPH2FSITsaZy-l5Lz_5quw3rmzhLwAR1tc0icgtR4MEpXEdsuQ7cyb12Xq-JLDrnATs0id5Vow9Ri_tE7Xe4BXgXaySn3aRPwWKoninVxVPVvETY3MXHSUEXV9OZ-pH5kYBLGYbLA== diff --git a/tests/features/journals/encrypted_jrnl-1-9-5.journal b/tests/features/journals/encrypted_jrnl-1-9-5.journal deleted file mode 100644 index 339b47baf9671f4550efeb9b6a0cfcd5032255d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 128 zcmV-`0Du3(bJIGVsY(mXmoW-2hF&*L`0NbJTYlTUr8*^Qm97}8E^3^1bZ$P^M diff --git a/tests/features/journals/little_endian_dates.journal b/tests/features/journals/little_endian_dates.journal deleted file mode 100644 index d7492969..00000000 --- a/tests/features/journals/little_endian_dates.journal +++ /dev/null @@ -1,5 +0,0 @@ -[09.06.2013 15:39] My first entry. -Everything is alright - -[10.07.2013 15:40] Life is good. -But I'm better. diff --git a/tests/features/journals/markdown-headings-335.journal b/tests/features/journals/markdown-headings-335.journal deleted file mode 100644 index 30f592ef..00000000 --- a/tests/features/journals/markdown-headings-335.journal +++ /dev/null @@ -1,42 +0,0 @@ -[2015-04-14 13:23] Heading Test - -H1-1 -= - -H1-2 -=== - -H1-3 -============================ - -H2-1 -- - -H2-2 ---- - -H2-3 ----------------------------------- - -Horizontal Rules (ignore) - ---- - -=== - -# ATX H1 - -## ATX H2 - -### ATX H3 - -#### ATX H4 - -##### ATX H5 - -###### ATX H6 - -Stuff - -More stuff -more stuff again diff --git a/tests/features/journals/mostlyreadabledates.journal b/tests/features/journals/mostlyreadabledates.journal deleted file mode 100644 index bd211bf5..00000000 --- a/tests/features/journals/mostlyreadabledates.journal +++ /dev/null @@ -1,8 +0,0 @@ -[2019-07-18 14:23] Entry subject -Time machines are possible. I know, because I've built one in my garage. - -[2019-07-19 14:23] Entry subject -I'm going to activate the machine. Nobody knows what comes next after this. Or before this? - -[2019-07 14:23] Entry subject -I've crossed so many timelines. Is there any going back? diff --git a/tests/features/journals/multiline-tags.journal b/tests/features/journals/multiline-tags.journal deleted file mode 100644 index 1fb8706f..00000000 --- a/tests/features/journals/multiline-tags.journal +++ /dev/null @@ -1,7 +0,0 @@ -[2013-06-09 15:39] Multiple @line entry with @tags. -Tag with @punctuation. afterwards -@TagOnLineAloneWithOutPunctuation -@TagOnLineAloneWithPunctuation. -Text before @tag. And After. -@hi. Hello -hi Hello \ No newline at end of file diff --git a/tests/features/journals/multiline.journal b/tests/features/journals/multiline.journal deleted file mode 100644 index 294ed141..00000000 --- a/tests/features/journals/multiline.journal +++ /dev/null @@ -1,5 +0,0 @@ -[2013-06-09 15:39] Multiple line entry. -This is the first line. -This line doesn't have any ending punctuation - -There is a blank line above this. diff --git a/tests/features/journals/simple.journal b/tests/features/journals/simple.journal deleted file mode 100644 index 8336068e..00000000 --- a/tests/features/journals/simple.journal +++ /dev/null @@ -1,5 +0,0 @@ -[2013-06-09 15:39] My first entry. -Everything is alright - -[2013-06-10 15:40] Life is good. -But I'm better. diff --git a/tests/features/journals/simple_jrnl-1-9-5.journal b/tests/features/journals/simple_jrnl-1-9-5.journal deleted file mode 100644 index 7bb6c5ac..00000000 --- a/tests/features/journals/simple_jrnl-1-9-5.journal +++ /dev/null @@ -1,13 +0,0 @@ -2010-06-10 15:00 A life without chocolate is like a bad analogy. - -2013-06-10 15:40 He said "[this] is the best time to be alive". -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada -quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque -augue et venenatis facilisis. - -[2019-08-03 12:55] Some chat log or something - -Suspendisse potenti. Sed dignissim sed nisl eu consequat. Aenean ante ex, -elementum ut interdum et, mattis eget lacus. In commodo nulla nec tellus -placerat, sed ultricies metus bibendum. Duis eget venenatis erat. In at dolor -dui. diff --git a/tests/features/journals/simple_jrnl-1-9-5_little_endian_dates.journal b/tests/features/journals/simple_jrnl-1-9-5_little_endian_dates.journal deleted file mode 100644 index 328b23f4..00000000 --- a/tests/features/journals/simple_jrnl-1-9-5_little_endian_dates.journal +++ /dev/null @@ -1,13 +0,0 @@ -10.06.2010 15:00 A life without chocolate is like a bad analogy. - -10.06.2013 15:40 He said "[this] is the best time to be alive". -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada -quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque -augue et venenatis facilisis. - -[03.08.2019 12:55] Some chat log or something - -Suspendisse potenti. Sed dignissim sed nisl eu consequat. Aenean ante ex, -elementum ut interdum et, mattis eget lacus. In commodo nulla nec tellus -placerat, sed ultricies metus bibendum. Duis eget venenatis erat. In at dolor -dui. diff --git a/tests/features/journals/tags-216.journal b/tests/features/journals/tags-216.journal deleted file mode 100644 index 08b6d630..00000000 --- a/tests/features/journals/tags-216.journal +++ /dev/null @@ -1,2 +0,0 @@ -[2013-06-10 15:40] I programmed for @OS/2. -Almost makes me want to go back to @C++, though. (Still better than @C#). diff --git a/tests/features/journals/tags-237.journal b/tests/features/journals/tags-237.journal deleted file mode 100644 index be050652..00000000 --- a/tests/features/journals/tags-237.journal +++ /dev/null @@ -1,3 +0,0 @@ -[2014-07-22 11:11] This entry has an email. -@Newline tag should show as a tag. -Kyla's @email is kyla@clevelandunderdog.org and Guinness's is guinness@fortheloveofpits.org. diff --git a/tests/features/journals/tags.journal b/tests/features/journals/tags.journal deleted file mode 100644 index a28f3159..00000000 --- a/tests/features/journals/tags.journal +++ /dev/null @@ -1,8 +0,0 @@ -[2013-04-09 15:39] I have an @idea: -(1) write a command line @journal software -(2) ??? -(3) PROFIT! - -[2013-06-10 15:40] I met with @dan. -As alway's he shared his latest @idea on how to rule the world with me. -inst diff --git a/tests/features/journals/unreadabledates.journal b/tests/features/journals/unreadabledates.journal deleted file mode 100644 index 53ef1d60..00000000 --- a/tests/features/journals/unreadabledates.journal +++ /dev/null @@ -1,5 +0,0 @@ -[ashasd7zdskhz7asdkjasd] Entry subject -I've lost track of time. - -[sadfhakjsdf88sdf7sdff] Entry subject -Time has no meaning. diff --git a/tests/features/journals/work.journal b/tests/features/journals/work.journal deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/features/templates/extension.md b/tests/features/templates/extension.md deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 93482ce9..fb3b1da1 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -36,15 +36,15 @@ def working_dir(request): def set_config(config_file, temp_dir, working_dir): # Copy the config file over config_source = os.path.join( - working_dir, "features", "data", "configs", config_file + 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, "features", "data", "journals") - journal_dest = os.path.join(temp_dir.name, "features", "journals") + journal_source = os.path.join(working_dir, "data", "journals") + journal_dest = os.path.join(temp_dir.name, "journals") shutil.copytree(journal_source, journal_dest) # @todo get rid of this by using default config values From 3055cca76795e92e55b5e4044baf1a095fb1a6c5 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 13 Feb 2021 18:38:27 -0800 Subject: [PATCH 092/215] Add tests for core feature to pytest-bdd - Implement "the output should contain" step Co-authored-by: Micah Jerome Ellison --- pyproject.toml | 4 ++++ tests/features/core.feature | 10 ++++++++++ tests/step_defs/conftest.py | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index b8c4731e..37a2f6b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,6 +65,10 @@ force_sort_within_sections = true [tool.pytest.ini_options] minversion = "6.0" +markers = [ + "todo", +] + [build-system] requires = ["poetry>=1.1"] diff --git a/tests/features/core.feature b/tests/features/core.feature index 67a73a12..4399341d 100644 --- a/tests/features/core.feature +++ b/tests/features/core.feature @@ -6,3 +6,13 @@ Feature: Functionality of jrnl outside of actually handling journals Then we should get no error Then the output should match "^jrnl version v\d+\.\d+(\.\d+)?(-(alpha|beta)\d*)?" + Scenario: Running the diagnostic command + Given we use the config "simple.yaml" + When we run "jrnl --diagnostic" + Then the output should contain "jrnl" + And the output should contain "Python" + And the output should contain "OS" + + @todo + Scenario: Listing available journals + diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index fb3b1da1..2e62c561 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -91,3 +91,10 @@ def matches_std_output(regex, cli_run): out = cli_run["stdout"] matches = re.findall(regex, out) assert matches, f"\nRegex didn't match:\n{regex}\n{str(out)}\n{str(matches)}" + + +@then(parse("the output should contain\n{text}")) +@then(parse('the output should contain "{text}"')) +def check_output_inline(text, cli_run): + assert text and text in cli_run['stdout'] + From 7657bd7221b8f42bff66e1896b867659045b26f5 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 13 Feb 2021 19:10:22 -0800 Subject: [PATCH 093/215] Implement version-checking test - Add new step definition Co-authored-by: Micah Jerome Ellison --- tests/step_defs/conftest.py | 12 ++++++++++++ tests/step_defs/test_features.py | 16 ++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 2e62c561..1ebfe974 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -5,6 +5,7 @@ import shutil import os import re import tempfile +import toml from pytest import fixture from pytest_bdd import given @@ -30,6 +31,11 @@ def temp_dir(): def working_dir(request): return os.path.join(request.config.rootpath, "tests") +@fixture +def toml_version(working_dir): + pyproject = os.path.join(working_dir, "..", "pyproject.toml") + pyproject_contents = toml.load(pyproject) + return pyproject_contents["tool"]["poetry"]["version"] # ----- STEPS ----- # @given(parse('we use the config "{config_file}"'), target_fixture="config_path") @@ -98,3 +104,9 @@ def matches_std_output(regex, cli_run): def check_output_inline(text, cli_run): assert text and text in cli_run['stdout'] + +@then("the output should contain pyproject.toml version") +def check_output_version_inline(cli_run, toml_version): + out = cli_run['stdout'] + assert toml_version in out, toml_version + diff --git a/tests/step_defs/test_features.py b/tests/step_defs/test_features.py index d670f9c9..b93f2140 100644 --- a/tests/step_defs/test_features.py +++ b/tests/step_defs/test_features.py @@ -1,3 +1,19 @@ from pytest_bdd import scenarios +scenarios("../features/build.feature") scenarios("../features/core.feature") +# scenarios("../features/datetime.feature") +# scenarios("../features/delete.feature") +# scenarios("../features/encrypt.feature") +# scenarios("../features/file_storage.feature") +# scenarios("../features/format.feature") +# scenarios("../features/import.feature") +# scenarios("../features/multiple_journals.feature") +# scenarios("../features/password.feature") +# scenarios("../features/search.feature") +# scenarios("../features/star.feature") +# scenarios("../features/tag.feature") +# scenarios("../features/upgrade.feature") +# scenarios("../features/write.feature") + + From c500730ae646d747e49677fbbb38870c1f3d4533 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 20 Feb 2021 12:28:48 -0800 Subject: [PATCH 094/215] Implement and add datetime tests - Deletes most of the datetime tests so that they can be re-added as they are implemented in pytest-bdd - Implements steps that check the journal and output for strings - Get rid of deployment tag (we're not using it, anyway) Co-authored-by: Micah Jerome Ellison --- tests/features/build.feature | 1 - tests/features/datetime.feature | 148 +------------------------------ tests/step_defs/conftest.py | 43 ++++++--- tests/step_defs/test_features.py | 4 +- 4 files changed, 36 insertions(+), 160 deletions(-) diff --git a/tests/features/build.feature b/tests/features/build.feature index 4725ea85..e9b47b49 100644 --- a/tests/features/build.feature +++ b/tests/features/build.feature @@ -1,6 +1,5 @@ Feature: Build process - @deployment_tests Scenario: Version numbers should stay in sync Given we use the config "simple.yaml" When we run "jrnl --version" diff --git a/tests/features/datetime.feature b/tests/features/datetime.feature index 8fe335c9..cbb31ff4 100644 --- a/tests/features/datetime.feature +++ b/tests/features/datetime.feature @@ -5,151 +5,7 @@ Feature: Reading and writing to journal with custom date formats Given we use the config "simple.yaml" When we run "jrnl 2013-11-30 15:42: Project Started." Then we should see the message "Entry added" - And the journal should contain "[2013-11-30 15:42] Project Started." + When we run "jrnl -999" + Then the output should contain "2013-11-30 15:42 Project Started." - Scenario: Dates can be in the future - # https://github.com/jrnl-org/jrnl/issues/185 - Given we use the config "simple.yaml" - When we run "jrnl 26/06/2099: Planet? Earth. Year? 2099." - Then we should see the message "Entry added" - And the journal should contain "[2099-06-26 09:00] Planet?" - Scenario: Loading a sample journal with custom date - Given we use the config "little_endian_dates.yaml" - When we run "jrnl -n 2" - Then we should get no error - And the output should be - """ - 09.06.2013 15:39 My first entry. - | Everything is alright - - 10.07.2013 15:40 Life is good. - | But I'm better. - """ - - Scenario Outline: Writing an entry from command line with custom date - Given we use the config ".yaml" - When we run "jrnl " - Then we should see the message "Entry added" - When we run "jrnl -n 1" - Then the output should contain "" - - Examples: Day-first Dates - | config | input | output | - | little_endian_dates | 2020-09-19: My first entry. | 19.09.2020 09:00 My first entry. | - | little_endian_dates | 2020-08-09: My second entry. | 09.08.2020 09:00 My second entry. | - | little_endian_dates | 2020-02-29: Test. | 29.02.2020 09:00 Test. | - | little_endian_dates | 2019-02-29: Test. | 2019-02-29: Test. | - | little_endian_dates | 2020-08-32: Test. | 2020-08-32: Test. | - | little_endian_dates | 2032-02-01: Test. | 01.02.2032 09:00 Test. | - | little_endian_dates | 2020-01-01: Test. | 01.01.2020 09:00 Test. | - | little_endian_dates | 2020-12-31: Test. | 31.12.2020 09:00 Test. | - - Scenario Outline: Searching for dates with custom date - Given we use the config ".yaml" - When we run "jrnl -on '' --short" - Then the output should be "" - - Examples: Day-first Dates - | config | input | output | - | little_endian_dates | 2013-07-10 | 10.07.2013 15:40 Life is good. | - | little_endian_dates | june 9 2013 | 09.06.2013 15:39 My first entry. | - | little_endian_dates | july 10 2013 | 10.07.2013 15:40 Life is good. | - | little_endian_dates | june 2013 | 09.06.2013 15:39 My first entry. | - | little_endian_dates | july 2013 | 10.07.2013 15:40 Life is good. | - # @todo month alone with no year should work - # | little_endian_dates | june | 09.06.2013 15:39 My first entry. | - # | little_endian_dates | july | 10.07.2013 15:40 Life is good. | - - Scenario: Writing an entry at the prompt with custom date - Given we use the config "little_endian_dates.yaml" - When we run "jrnl" and enter "2013-05-10: I saw Elvis. He's alive." - Then we should get no error - And the journal should contain "[10.05.2013 09:00] I saw Elvis." - And the journal should contain "He's alive." - - Scenario: Viewing today's entries does not print the entire journal - # https://github.com/jrnl-org/jrnl/issues/741 - Given we use the config "simple.yaml" - When we run "jrnl -on today" - Then the output should not contain "Life is good" - And the output should not contain "But I'm better." - - Scenario Outline: Create entry using day of the week as entry date. - Given we use the config "simple.yaml" - When we run "jrnl : This is an entry on a ." - Then we should see the message "Entry added" - When we run "jrnl -1" - Then the output should contain " at 9am" in the local time - And the output should contain "This is an entry on a ." - - Examples: Days of the week - | day | - | Monday | - | Tuesday | - | Wednesday | - | Thursday | - | Friday | - | Saturday | - | Sunday | - | sunday | - | sUndAy | - - Scenario Outline: Create entry using day of the week abbreviations as entry date. - Given we use the config "simple.yaml" - When we run "jrnl : This is an entry on a ." - Then we should see the message "Entry added" - When we run "jrnl -1" - Then the output should contain " at 9am" in the local time - - Examples: Days of the week - | day | weekday | - | mon | Monday | - | tue | Tuesday | - | wed | Wednesday | - | thu | Thursday | - | fri | Friday | - | sat | Saturday | - | sun | Sunday | - - Scenario: Journals with unreadable dates should still be loaded - Given we use the config "unreadabledates.yaml" - When we run "jrnl -2" - Then the output should contain "I've lost track of time." - And the output should contain "Time has no meaning." - - Scenario: Journals with readable dates AND unreadable dates should still contain all data. - Given we use the config "mostlyreadabledates.yaml" - When we run "jrnl -3" - Then the output should contain "Time machines are possible." - Then the output should contain "I'm going to activate the machine." - And the output should contain "I've crossed so many timelines. Is there any going back?" - And the journal should have 3 entries - - Scenario: Update near-valid dates after journal is edited - Given we use the config "mostlyreadabledates.yaml" - When we run "jrnl 2222-08-19: I have made it exactly one month into the future." - Then the journal should contain "[2019-07-01 14:23] Entry subject" - - Scenario: Integers in square brackets should not be read as dates - Given we use the config "brackets.yaml" - When we run "jrnl -1" - Then the output should contain "[1] line starting with 1" - - # broken still - @skip - Scenario: Dayone entries without timezone information are interpreted in current timezone - Given we use the config "dayone.yaml" - When we run "jrnl -until 'feb 2013'" - Then we should get no error - And the output should contain "2013-01-17T18:37Z" in the local time - - Scenario: Loading entry with ambiguous time stamp in timezone-aware journal (like Dayone) - #https://github.com/jrnl-org/jrnl/issues/153 - Given we use the config "bug153.yaml" - When we run "jrnl -1" - Then we should get no error - And the output should be - """ - 2013-10-27 03:27 Some text. - """ diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 1ebfe974..a764d090 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -1,49 +1,60 @@ # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html -import shutil import os import re +import shutil import tempfile -import toml +from unittest.mock import patch -from pytest import fixture from pytest_bdd import given from pytest_bdd import then from pytest_bdd import when from pytest_bdd.parsers import parse -from unittest.mock import patch +from pytest import fixture +import toml from jrnl import __version__ -from jrnl.os_compat import split_args from jrnl.cli import cli +from jrnl.os_compat import split_args + # ----- FIXTURES ----- # @fixture def cli_run(): return {"status": 0, "stdout": None, "stderr": None} + @fixture def temp_dir(): return tempfile.TemporaryDirectory() + @fixture def working_dir(request): return os.path.join(request.config.rootpath, "tests") + @fixture def toml_version(working_dir): pyproject = os.path.join(working_dir, "..", "pyproject.toml") pyproject_contents = toml.load(pyproject) return pyproject_contents["tool"]["poetry"]["version"] + +@fixture +def read_journal(journal_name="default"): + configuration = load_config(context.config_path) + with open(configuration["journals"][journal_name]) as journal_file: + journal = journal_file.read() + return journal + + # ----- STEPS ----- # @given(parse('we use the config "{config_file}"'), target_fixture="config_path") def set_config(config_file, temp_dir, working_dir): # Copy the config file over - config_source = os.path.join( - working_dir, "data", "configs", config_file - ) + 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) @@ -102,11 +113,23 @@ def matches_std_output(regex, cli_run): @then(parse("the output should contain\n{text}")) @then(parse('the output should contain "{text}"')) def check_output_inline(text, cli_run): - assert text and text in cli_run['stdout'] + assert text and text in cli_run["stdout"] @then("the output should contain pyproject.toml version") def check_output_version_inline(cli_run, toml_version): - out = cli_run['stdout'] + out = cli_run["stdout"] assert toml_version in out, toml_version + +@then(parse('we should see the message "{text}"')) +def check_message(text, cli_run): + out = cli_run["stderr"] + assert text in out, [text, out] + + +@then(parse('the journal should contain "{text}"')) +@then(parse('journal "{journal_name}" should contain "{text}"')) +def check_journal_content(context, text, journal_name="default"): + journal = read_journal(context, journal_name) + assert text in journal, journal diff --git a/tests/step_defs/test_features.py b/tests/step_defs/test_features.py index b93f2140..5426d0c0 100644 --- a/tests/step_defs/test_features.py +++ b/tests/step_defs/test_features.py @@ -2,7 +2,7 @@ from pytest_bdd import scenarios scenarios("../features/build.feature") scenarios("../features/core.feature") -# scenarios("../features/datetime.feature") +scenarios("../features/datetime.feature") # scenarios("../features/delete.feature") # scenarios("../features/encrypt.feature") # scenarios("../features/file_storage.feature") @@ -15,5 +15,3 @@ scenarios("../features/core.feature") # scenarios("../features/tag.feature") # scenarios("../features/upgrade.feature") # scenarios("../features/write.feature") - - From 7974f3026160caa9e6d0fe7e5fdb9c7d04e42f95 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 20 Feb 2021 13:18:35 -0800 Subject: [PATCH 095/215] Make tests move into temp dir as they run This will prevent any unexpected files from showing up anywhere outside the temp dir Co-authored-by: Micah Jerome Ellison --- tests/features/datetime.feature | 22 ++++++++++++++++++++++ tests/step_defs/conftest.py | 20 +++++++++++++------- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/tests/features/datetime.feature b/tests/features/datetime.feature index cbb31ff4..ca82e8c0 100644 --- a/tests/features/datetime.feature +++ b/tests/features/datetime.feature @@ -9,3 +9,25 @@ Feature: Reading and writing to journal with custom date formats Then the output should contain "2013-11-30 15:42 Project Started." + Scenario: Dates can be in the future + # https://github.com/jrnl-org/jrnl/issues/185 + Given we use the config "simple.yaml" + When we run "jrnl 26/06/2099: Planet? Earth. Year? 2099." + Then we should see the message "Entry added" + When we run "jrnl -999" + Then the output should contain "2099-06-26 09:00 Planet?" + + + Scenario: Loading a sample journal with custom date + Given we use the config "little_endian_dates.yaml" + When we run "jrnl -n 2" + Then we should get no error + When we run "jrnl -n 999" + Then the output should be + 09.06.2013 15:39 My first entry. + | Everything is alright + + 10.07.2013 15:40 Life is good. + | But I'm better. + + diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index a764d090..0eec48ed 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -53,6 +53,9 @@ def read_journal(journal_name="default"): # ----- STEPS ----- # @given(parse('we use the config "{config_file}"'), target_fixture="config_path") def set_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) @@ -61,7 +64,7 @@ def set_config(config_file, temp_dir, working_dir): # @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, "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 @@ -116,6 +119,15 @@ def check_output_inline(text, cli_run): assert text and text in cli_run["stdout"] +@then(parse('the output should be "{expected_out}"')) +@then(parse("the output should be\n{expected_out}")) +def check_output(cli_run, expected_out): + expected_out = expected_out.strip() + actual_out = cli_run["stdout"].strip() + assert expected_out == actual_out, \ + f"Output does not match.\nExpected:\n{expected_out}\n---end---\nActual:\n{actual_out}\n---end---\n" + + @then("the output should contain pyproject.toml version") def check_output_version_inline(cli_run, toml_version): out = cli_run["stdout"] @@ -127,9 +139,3 @@ def check_message(text, cli_run): out = cli_run["stderr"] assert text in out, [text, out] - -@then(parse('the journal should contain "{text}"')) -@then(parse('journal "{journal_name}" should contain "{text}"')) -def check_journal_content(context, text, journal_name="default"): - journal = read_journal(context, journal_name) - assert text in journal, journal From e257194d177c8590accaef0c5f5f508c848028b7 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 20 Feb 2021 14:00:40 -0800 Subject: [PATCH 096/215] Add scenario outline test to datetime - Allow config step to support scenario outlines - Add another datetime test - Get rid of read journal step since it doesn't work with other journal types (we should rely on jrnl knowing how to parse each jrnl type for better tests) Co-authored-by: Micah Jerome Ellison --- tests/features/datetime.feature | 17 +++++++++++++++++ tests/step_defs/conftest.py | 31 +++++++++++++------------------ 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/tests/features/datetime.feature b/tests/features/datetime.feature index ca82e8c0..d28092ce 100644 --- a/tests/features/datetime.feature +++ b/tests/features/datetime.feature @@ -31,3 +31,20 @@ Feature: Reading and writing to journal with custom date formats | But I'm better. + Scenario Outline: Writing an entry from command line with custom date + Given we use the config "" + When we run "jrnl " + Then we should see the message "Entry added" + When we run "jrnl -n 1" + Then the output should contain "" + + Examples: Day-first Dates + | config_file | command | output | + | little_endian_dates.yaml | 2020-09-19: My first entry. | 19.09.2020 09:00 My first entry. | + | little_endian_dates.yaml | 2020-08-09: My second entry. | 09.08.2020 09:00 My second entry. | + | little_endian_dates.yaml | 2020-02-29: Test. | 29.02.2020 09:00 Test. | + | little_endian_dates.yaml | 2019-02-29: Test. | 2019-02-29: Test. | + | little_endian_dates.yaml | 2020-08-32: Test. | 2020-08-32: Test. | + | little_endian_dates.yaml | 2032-02-01: Test. | 01.02.2032 09:00 Test. | + | little_endian_dates.yaml | 2020-01-01: Test. | 01.01.2020 09:00 Test. | + | little_endian_dates.yaml | 2020-12-31: Test. | 31.12.2020 09:00 Test. | diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 0eec48ed..99825ff8 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -42,16 +42,9 @@ def toml_version(working_dir): return pyproject_contents["tool"]["poetry"]["version"] -@fixture -def read_journal(journal_name="default"): - configuration = load_config(context.config_path) - with open(configuration["journals"][journal_name]) as journal_file: - journal = journal_file.read() - return journal - - # ----- STEPS ----- # @given(parse('we use the config "{config_file}"'), target_fixture="config_path") +@given('we use the config ""', target_fixture="config_path") def set_config(config_file, temp_dir, working_dir): # Move into temp dir as cwd os.chdir(temp_dir.name) @@ -77,7 +70,8 @@ def set_config(config_file, temp_dir, working_dir): return config_dest -@when(parse('we run "{command}"')) +@when(parse('we run "jrnl {command}"')) +@when('we run "jrnl "') def run(command, config_path, cli_run, capsys): args = split_args(command) status = 0 @@ -85,12 +79,12 @@ def run(command, config_path, cli_run, capsys): # fmt: off # see: https://github.com/psf/black/issues/664 with \ - patch("sys.argv", args), \ + patch("sys.argv", ['jrnl'] + args), \ patch("jrnl.config.get_config_path", side_effect=lambda: config_path), \ patch("jrnl.install.get_config_path", side_effect=lambda: config_path) \ : try: - cli(args[1:]) + cli(args) except SystemExit as e: status = e.code # fmt: on @@ -113,10 +107,11 @@ def matches_std_output(regex, cli_run): assert matches, f"\nRegex didn't match:\n{regex}\n{str(out)}\n{str(matches)}" -@then(parse("the output should contain\n{text}")) -@then(parse('the output should contain "{text}"')) -def check_output_inline(text, cli_run): - assert text and text in cli_run["stdout"] +@then(parse("the output should contain\n{output}")) +@then(parse('the output should contain "{output}"')) +@then('the output should contain ""') +def check_output_inline(output, cli_run): + assert output and output in cli_run["stdout"] @then(parse('the output should be "{expected_out}"')) @@ -124,8 +119,9 @@ def check_output_inline(text, cli_run): def check_output(cli_run, expected_out): expected_out = expected_out.strip() actual_out = cli_run["stdout"].strip() - assert expected_out == actual_out, \ - f"Output does not match.\nExpected:\n{expected_out}\n---end---\nActual:\n{actual_out}\n---end---\n" + assert ( + expected_out == actual_out + ), f"Output does not match.\nExpected:\n{expected_out}\n---end---\nActual:\n{actual_out}\n---end---\n" @then("the output should contain pyproject.toml version") @@ -138,4 +134,3 @@ def check_output_version_inline(cli_run, toml_version): def check_message(text, cli_run): out = cli_run["stderr"] assert text in out, [text, out] - From 6b096761e070f705ba810acfd41b68b0c4614b65 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 20 Feb 2021 14:15:26 -0800 Subject: [PATCH 097/215] Re-enable test for windows on python 3.9 Co-authored-by: Micah Jerome Ellison --- .github/workflows/testing.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index c5015d5f..a90b939a 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -27,9 +27,6 @@ jobs: matrix: python-version: [ 3.7, 3.8, 3.9 ] os: [ ubuntu-latest, macos-latest, windows-latest ] - exclude: # Added for GitHub Actions PR problem 2020-12-19 -- remove later! - - os: windows-latest - python-version: 3.9 steps: - uses: actions/checkout@v2 From be05f96c2671104253a4bf21ec289fd76c31915c Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 20 Feb 2021 15:12:17 -0800 Subject: [PATCH 098/215] Implement "the output should be" step - Add another datetime test Co-authored-by: Micah Jerome Ellison --- tests/features/datetime.feature | 19 +++++++++++++++++++ tests/step_defs/conftest.py | 11 +++++++++++ 2 files changed, 30 insertions(+) diff --git a/tests/features/datetime.feature b/tests/features/datetime.feature index d28092ce..5c66b093 100644 --- a/tests/features/datetime.feature +++ b/tests/features/datetime.feature @@ -48,3 +48,22 @@ Feature: Reading and writing to journal with custom date formats | little_endian_dates.yaml | 2032-02-01: Test. | 01.02.2032 09:00 Test. | | little_endian_dates.yaml | 2020-01-01: Test. | 01.01.2020 09:00 Test. | | little_endian_dates.yaml | 2020-12-31: Test. | 31.12.2020 09:00 Test. | + + + Scenario Outline: Searching for dates with custom date + Given we use the config "" + When we run "jrnl " + Then the output should be "" + + Examples: Day-first Dates + | config_file | command | output | + | little_endian_dates.yaml | -on '2013-07-10' --short | 10.07.2013 15:40 Life is good. | + | little_endian_dates.yaml | -on 'june 9 2013' --short | 09.06.2013 15:39 My first entry. | + | little_endian_dates.yaml | -on 'july 10 2013' --short | 10.07.2013 15:40 Life is good. | + | little_endian_dates.yaml | -on 'june 2013' --short | 09.06.2013 15:39 My first entry. | + | little_endian_dates.yaml | -on 'july 2013' --short | 10.07.2013 15:40 Life is good. | + # @todo month alone with no year should work + # | little_endian_dates.yaml | -on 'june' --short | 09.06.2013 15:39 My first entry. | + # | little_endian_dates.yaml | -on 'july' --short | 10.07.2013 15:40 Life is good. | + + diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 99825ff8..c6ad8d6a 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -114,6 +114,17 @@ def check_output_inline(output, cli_run): assert output and output in cli_run["stdout"] +@then(parse("the output should be\n{output}")) +@then(parse('the output should be "{output}"')) +@then('the output should be ""') +def test_check_output_inline(output, cli_run): + actual_out = cli_run["stdout"].strip() + output = output.strip() + assert ( + output and output == actual_out + ), f"Output does not match.\nExpected:\n{output}\n---end---\nActual:\n{actual_out}\n---end---\n" + + @then(parse('the output should be "{expected_out}"')) @then(parse("the output should be\n{expected_out}")) def check_output(cli_run, expected_out): From 74ae5f039b5e9d3c017f60296b253567d6229230 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 20 Feb 2021 15:20:02 -0800 Subject: [PATCH 099/215] Rename test functions for clarity Co-authored-by: Micah Jerome Ellison --- tests/step_defs/conftest.py | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index c6ad8d6a..3c2c0287 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -19,6 +19,11 @@ from jrnl.cli import cli from jrnl.os_compat import split_args +# ----- UTILS ----- # +def failed_msg(msg, expected, actual): + return f"{msg}\nExpected:\n{expected}\n---end---\nActual:\n{actual}\n---end---\n" + + # ----- FIXTURES ----- # @fixture def cli_run(): @@ -45,7 +50,7 @@ def toml_version(working_dir): # ----- STEPS ----- # @given(parse('we use the config "{config_file}"'), target_fixture="config_path") @given('we use the config ""', target_fixture="config_path") -def set_config(config_file, temp_dir, working_dir): +def we_use_the_config(config_file, temp_dir, working_dir): # Move into temp dir as cwd os.chdir(temp_dir.name) @@ -72,7 +77,7 @@ def set_config(config_file, temp_dir, working_dir): @when(parse('we run "jrnl {command}"')) @when('we run "jrnl "') -def run(command, config_path, cli_run, capsys): +def we_run(command, config_path, cli_run, capsys): args = split_args(command) status = 0 @@ -96,12 +101,12 @@ def run(command, config_path, cli_run, capsys): @then("we should get no error") -def no_error(cli_run): +def should_get_no_error(cli_run): assert cli_run["status"] == 0, cli_run["status"] @then(parse('the output should match "{regex}"')) -def matches_std_output(regex, cli_run): +def output_should_match(regex, cli_run): out = cli_run["stdout"] matches = re.findall(regex, out) assert matches, f"\nRegex didn't match:\n{regex}\n{str(out)}\n{str(matches)}" @@ -110,38 +115,28 @@ def matches_std_output(regex, cli_run): @then(parse("the output should contain\n{output}")) @then(parse('the output should contain "{output}"')) @then('the output should contain ""') -def check_output_inline(output, cli_run): +def output_should_contain(output, cli_run): assert output and output in cli_run["stdout"] @then(parse("the output should be\n{output}")) @then(parse('the output should be "{output}"')) @then('the output should be ""') -def test_check_output_inline(output, cli_run): +def output_should_be(output, cli_run): actual_out = cli_run["stdout"].strip() output = output.strip() assert ( output and output == actual_out - ), f"Output does not match.\nExpected:\n{output}\n---end---\nActual:\n{actual_out}\n---end---\n" - - -@then(parse('the output should be "{expected_out}"')) -@then(parse("the output should be\n{expected_out}")) -def check_output(cli_run, expected_out): - expected_out = expected_out.strip() - actual_out = cli_run["stdout"].strip() - assert ( - expected_out == actual_out - ), f"Output does not match.\nExpected:\n{expected_out}\n---end---\nActual:\n{actual_out}\n---end---\n" + ), failed_msg('Output does not match.', output, actual_out) @then("the output should contain pyproject.toml version") -def check_output_version_inline(cli_run, toml_version): +def output_should_contain_version(cli_run, toml_version): out = cli_run["stdout"] assert toml_version in out, toml_version @then(parse('we should see the message "{text}"')) -def check_message(text, cli_run): +def should_see_the_message(text, cli_run): out = cli_run["stderr"] assert text in out, [text, out] From 72170304efa14509df9f387ba292139dc626a0d1 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 20 Feb 2021 18:41:07 -0800 Subject: [PATCH 100/215] Expand "we run" step in pytest-bdd - Add some necessary fixtures - Add datetime test - Implement "the output should not contain" step - Implement "the output should contain the date" step Co-authored-by: Micah Jerome Ellison --- tests/features/datetime.feature | 36 +++++++++++++++++++++++++++++++++ tests/step_defs/conftest.py | 30 ++++++++++++++++++++++++--- 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/tests/features/datetime.feature b/tests/features/datetime.feature index 5c66b093..0dd02b86 100644 --- a/tests/features/datetime.feature +++ b/tests/features/datetime.feature @@ -67,3 +67,39 @@ Feature: Reading and writing to journal with custom date formats # | little_endian_dates.yaml | -on 'july' --short | 10.07.2013 15:40 Life is good. | + Scenario: Writing an entry at the prompt with custom date + Given we use the config "little_endian_dates.yaml" + When we run "jrnl" and enter "2013-05-10: I saw Elvis. He's alive." + Then we should get no error + When we run "jrnl -999" + Then the output should contain "10.05.2013 09:00 I saw Elvis." + And the output should contain "He's alive." + + + Scenario: Viewing today's entries does not print the entire journal + # see: https://github.com/jrnl-org/jrnl/issues/741 + Given we use the config "simple.yaml" + When we run "jrnl -on today" + Then the output should not contain "Life is good" + And the output should not contain "But I'm better." + + + Scenario Outline: Create entry using day of the week as entry date. + Given we use the config "simple.yaml" + When we run "jrnl " + Then we should see the message "Entry added" + When we run "jrnl -1" + Then the output should contain "" + Then the output should contain the date "" + + Examples: Days of the week + | command | output | date | + | Monday: entry on a monday | entry on a monday | monday at 9am | + | Tuesday: entry on a tuesday | entry on a tuesday | tuesday at 9am | + | Wednesday: entry on a wednesday | entry on a wednesday | wednesday at 9am | + | Thursday: entry on a thursday | entry on a thursday | thursday at 9am | + | Friday: entry on a friday | entry on a friday | friday at 9am | + | Saturday: entry on a saturday | entry on a saturday | saturday at 9am | + | Sunday: entry on a sunday | entry on a sunday | sunday at 9am | + | sunday: entry on a sunday | entry on a sunday | sunday at 9am | + | sUndAy: entry on a sunday | entry on a sunday | sunday at 9am | diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 3c2c0287..995b5154 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -47,6 +47,16 @@ def toml_version(working_dir): return pyproject_contents["tool"]["poetry"]["version"] +@fixture +def command(): + return '' + + +@fixture +def user_input(): + return '' + + # ----- STEPS ----- # @given(parse('we use the config "{config_file}"'), target_fixture="config_path") @given('we use the config ""', target_fixture="config_path") @@ -77,7 +87,9 @@ def we_use_the_config(config_file, temp_dir, working_dir): @when(parse('we run "jrnl {command}"')) @when('we run "jrnl "') -def we_run(command, config_path, cli_run, capsys): +@when('we run "jrnl"') +@when(parse('we run "jrnl" and enter "{user_input}"')) +def we_run(command, config_path, user_input, cli_run, capsys): args = split_args(command) status = 0 @@ -85,8 +97,8 @@ def we_run(command, config_path, cli_run, capsys): # see: https://github.com/psf/black/issues/664 with \ patch("sys.argv", ['jrnl'] + args), \ - patch("jrnl.config.get_config_path", side_effect=lambda: config_path), \ - patch("jrnl.install.get_config_path", side_effect=lambda: config_path) \ + patch("sys.stdin.read", return_value=user_input) as mock_read, \ + patch("jrnl.install.get_config_path", return_value=config_path) \ : try: cli(args) @@ -119,6 +131,13 @@ def output_should_contain(output, cli_run): assert output and output in cli_run["stdout"] +@then(parse("the output should not contain\n{output}")) +@then(parse('the output should not contain "{output}"')) +@then('the output should not contain ""') +def output_should_contain(output, cli_run): + assert output not in cli_run["stdout"] + + @then(parse("the output should be\n{output}")) @then(parse('the output should be "{output}"')) @then('the output should be ""') @@ -130,6 +149,11 @@ def output_should_be(output, cli_run): ), failed_msg('Output does not match.', output, actual_out) +@then('the output should contain the date ""') +def output_should_contain(output, cli_run): + assert output and output in cli_run["stdout"] + + @then("the output should contain pyproject.toml version") def output_should_contain_version(cli_run, toml_version): out = cli_run["stdout"] From 7d04fb904a8698e872cb175ae0d16e9fcae10615 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Tue, 23 Feb 2021 18:23:48 -0800 Subject: [PATCH 101/215] Add abbreviated weekday test Co-authored-by: Jonathan Wren --- tests/features/datetime.feature | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/features/datetime.feature b/tests/features/datetime.feature index 0dd02b86..8191f772 100644 --- a/tests/features/datetime.feature +++ b/tests/features/datetime.feature @@ -103,3 +103,23 @@ Feature: Reading and writing to journal with custom date formats | Sunday: entry on a sunday | entry on a sunday | sunday at 9am | | sunday: entry on a sunday | entry on a sunday | sunday at 9am | | sUndAy: entry on a sunday | entry on a sunday | sunday at 9am | + + Scenario Outline: Create entry using day of the week as entry date. + Given we use the config "simple.yaml" + When we run "jrnl " + Then we should see the message "Entry added" + When we run "jrnl -1" + Then the output should contain "" + Then the output should contain the date "" + + Examples: Days of the week + | command | output | date | + | Mon: entry on a monday | entry on a monday | monday at 9am | + | Tue: entry on a tuesday | entry on a tuesday | tuesday at 9am | + | Wed: entry on a wednesday | entry on a wednesday | wednesday at 9am | + | Thu: entry on a thursday | entry on a thursday | thursday at 9am | + | Fri: entry on a friday | entry on a friday | friday at 9am | + | Sat: entry on a saturday | entry on a saturday | saturday at 9am | + | Sun: entry on a sunday | entry on a sunday | sunday at 9am | + | sun: entry on a sunday | entry on a sunday | sunday at 9am | + | sUn: entry on a sunday | entry on a sunday | sunday at 9am | From 7e6dd354cf09faf3d641e7dff36f100d558b717c Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Tue, 23 Feb 2021 18:26:21 -0800 Subject: [PATCH 102/215] Add unreadable date test Co-authored-by: Jonathan Wren --- tests/features/datetime.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/features/datetime.feature b/tests/features/datetime.feature index 8191f772..0bccfd65 100644 --- a/tests/features/datetime.feature +++ b/tests/features/datetime.feature @@ -123,3 +123,9 @@ Feature: Reading and writing to journal with custom date formats | Sun: entry on a sunday | entry on a sunday | sunday at 9am | | sun: entry on a sunday | entry on a sunday | sunday at 9am | | sUn: entry on a sunday | entry on a sunday | sunday at 9am | + + Scenario: Journals with unreadable dates should still be loaded + Given we use the config "unreadabledates.yaml" + When we run "jrnl -2" + Then the output should contain "I've lost track of time." + And the output should contain "Time has no meaning." From f686e2b9f0d9ad684c41fa2bff295ce0c45f11b3 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Tue, 23 Feb 2021 18:40:56 -0800 Subject: [PATCH 103/215] Fix local config overwrite when running pytest bdd Co-authored-by: Jonathan Wren --- tests/step_defs/conftest.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 995b5154..4933a3eb 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -98,8 +98,9 @@ def we_run(command, config_path, user_input, cli_run, capsys): with \ patch("sys.argv", ['jrnl'] + args), \ patch("sys.stdin.read", return_value=user_input) as mock_read, \ - patch("jrnl.install.get_config_path", return_value=config_path) \ - : + patch("jrnl.install.get_config_path", return_value=config_path), \ + patch("jrnl.config.get_config_path", return_value=config_path) \ + : # @TODO: single point of truth for get_config_path (move from all calls from install to config) try: cli(args) except SystemExit as e: From 0c9b6cf85f5b91dca1913cd50d48cb1acd228c97 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Tue, 23 Feb 2021 18:56:10 -0800 Subject: [PATCH 104/215] Add unreadable date test Co-authored-by: Jonathan Wren --- tests/data/journals/mostlyreadabledates.journal | 6 +++--- tests/features/datetime.feature | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/data/journals/mostlyreadabledates.journal b/tests/data/journals/mostlyreadabledates.journal index bd211bf5..625ebcf2 100644 --- a/tests/data/journals/mostlyreadabledates.journal +++ b/tests/data/journals/mostlyreadabledates.journal @@ -1,8 +1,8 @@ -[2019-07-18 14:23] Entry subject +[2019-07-18 14:23] The first entry Time machines are possible. I know, because I've built one in my garage. -[2019-07-19 14:23] Entry subject +[2019-07-19 14:23] The second entry I'm going to activate the machine. Nobody knows what comes next after this. Or before this? -[2019-07 14:23] Entry subject +[2019-07 14:23] The third entry I've crossed so many timelines. Is there any going back? diff --git a/tests/features/datetime.feature b/tests/features/datetime.feature index 0bccfd65..c269c188 100644 --- a/tests/features/datetime.feature +++ b/tests/features/datetime.feature @@ -129,3 +129,11 @@ Feature: Reading and writing to journal with custom date formats When we run "jrnl -2" Then the output should contain "I've lost track of time." And the output should contain "Time has no meaning." + + Scenario: Journals with readable dates AND unreadable dates should still contain all data. + Given we use the config "mostlyreadabledates.yaml" + When we run "jrnl --short" + Then the output should be + 2019-07-01 14:23 The third entry + 2019-07-18 14:23 The first entry + 2019-07-19 14:23 The second entry From a529ee5d066c79cf3c9fccad8fdbe0c2d1dde66f Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Tue, 23 Feb 2021 19:01:59 -0800 Subject: [PATCH 105/215] Add another unreadable/readable date test Co-authored-by: Jonathan Wren --- tests/features/datetime.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/features/datetime.feature b/tests/features/datetime.feature index c269c188..d6025a4a 100644 --- a/tests/features/datetime.feature +++ b/tests/features/datetime.feature @@ -137,3 +137,9 @@ Feature: Reading and writing to journal with custom date formats 2019-07-01 14:23 The third entry 2019-07-18 14:23 The first entry 2019-07-19 14:23 The second entry + + Scenario: Update near-valid dates after journal is edited + Given we use the config "mostlyreadabledates.yaml" + When we run "jrnl 2222-08-19: I have made it exactly one month into the future." + When we run "jrnl -2" + Then the output should contain "2019-07-19 14:23 The second entry" From 7ccadebca0c6c489e7717e1fcccbb69f7e2037fe Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Tue, 23 Feb 2021 19:03:57 -0800 Subject: [PATCH 106/215] Finish migrating datetime.feature to pytest bdd Co-authored-by: Jonathan Wren --- tests/features/datetime.feature | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/features/datetime.feature b/tests/features/datetime.feature index d6025a4a..b0f9d2b0 100644 --- a/tests/features/datetime.feature +++ b/tests/features/datetime.feature @@ -143,3 +143,24 @@ Feature: Reading and writing to journal with custom date formats When we run "jrnl 2222-08-19: I have made it exactly one month into the future." When we run "jrnl -2" Then the output should contain "2019-07-19 14:23 The second entry" + + Scenario: Integers in square brackets should not be read as dates + Given we use the config "brackets.yaml" + When we run "jrnl -1" + Then the output should contain "[1] line starting with 1" + + # broken still + @skip + Scenario: Dayone entries without timezone information are interpreted in current timezone + Given we use the config "dayone.yaml" + When we run "jrnl -until 'feb 2013'" + Then we should get no error + And the output should contain "2013-01-17T18:37Z" in the local time + + Scenario: Loading entry with ambiguous time stamp in timezone-aware journal (like Dayone) + #https://github.com/jrnl-org/jrnl/issues/153 + Given we use the config "bug153.yaml" + When we run "jrnl -1" + Then we should get no error + And the output should be + 2013-10-27 03:27 Some text. From 8754837f157c4e02c931a6280756f58c1f32ce43 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Tue, 23 Feb 2021 19:54:41 -0800 Subject: [PATCH 107/215] Add some functioning delete tests Co-authored-by: Jonathan Wren --- tests/features/delete.feature | 236 ++++--------------------------- tests/step_defs/conftest.py | 17 ++- tests/step_defs/test_features.py | 2 +- 3 files changed, 45 insertions(+), 210 deletions(-) diff --git a/tests/features/delete.feature b/tests/features/delete.feature index 2fc3f8f7..0613c826 100644 --- a/tests/features/delete.feature +++ b/tests/features/delete.feature @@ -1,229 +1,53 @@ Feature: Delete entries from journal Scenario Outline: Delete flag allows deletion of single entry - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl -1" Then the output should contain "2020-09-24 09:14 The third entry finally" When we run "jrnl --delete" and enter - """ - N - N - Y - """ - Then we flush the output + N + N + Y When we run "jrnl -99 --short" Then the output should be - """ - 2020-08-29 11:11 Entry the first. - 2020-08-31 14:32 A second entry in what I hope to be a long series. - """ + 2020-08-29 11:11 Entry the first. + 2020-08-31 14:32 A second entry in what I hope to be a long series. Examples: Configs - | config | - | basic_onefile | - | basic_encrypted | - # | basic_folder | @todo - # | basic_dayone | @todo - + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + # | basic_folder.yaml | @todo + # | basic_dayone.yaml | @todo + Scenario Outline: Backing out of interactive delete does not change journal - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl --delete -n 1" and enter - """ - N - """ - Then we flush the output + N When we run "jrnl -99 --short" Then the output should be - """ - 2020-08-29 11:11 Entry the first. - 2020-08-31 14:32 A second entry in what I hope to be a long series. - 2020-09-24 09:14 The third entry finally after weeks without writing. - """ + 2020-08-29 11:11 Entry the first. + 2020-08-31 14:32 A second entry in what I hope to be a long series. + 2020-09-24 09:14 The third entry finally after weeks without writing. Examples: Configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | - + | config_file | + | basic_onefile.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | + Scenario Outline: Delete flag with nonsense input deletes nothing (issue #932) - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl --delete asdfasdf" - Then we flush the output When we run "jrnl -99 --short" Then the output should be - """ - 2020-08-29 11:11 Entry the first. - 2020-08-31 14:32 A second entry in what I hope to be a long series. - 2020-09-24 09:14 The third entry finally after weeks without writing. - """ + 2020-08-29 11:11 Entry the first. + 2020-08-31 14:32 A second entry in what I hope to be a long series. + 2020-09-24 09:14 The third entry finally after weeks without writing. Examples: Configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | - - Scenario Outline: Delete flag with tag only deletes tagged entries - Given we use the config ".yaml" - When we run "jrnl --delete @ipsum" and enter - """ - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-31 14:32 A second entry in what I hope to be a long series. - 2020-09-24 09:14 The third entry finally after weeks without writing. - """ - - Examples: Configs - | config | - | basic_onefile | - # | basic_folder | @todo - # | basic_dayone | @todo - - - Scenario Outline: Delete flag with multiple tags deletes all entries matching any of the tags - Given we use the config ".yaml" - When we run "jrnl --delete @ipsum @tagthree" and enter - """ - Y - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-31 14:32 A second entry in what I hope to be a long series. - """ - - Examples: Configs - | config | - | basic_onefile | - # | basic_folder | @todo - # | basic_dayone | @todo - - Scenario Outline: Delete flag with -and deletes boolean AND of tagged entries - Given we use the config ".yaml" - When we run "jrnl --delete -and @tagone @tagtwo" and enter - """ - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-31 14:32 A second entry in what I hope to be a long series. - 2020-09-24 09:14 The third entry finally after weeks without writing. - """ - - Examples: Configs - | config | - | basic_onefile | - # | basic_folder | @todo - # | basic_dayone | @todo - - Scenario Outline: Delete flag with -not does not delete entries from given tag - Given we use the config ".yaml" - When we run "jrnl --delete @tagone -not @ipsum" and enter - """ - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-29 11:11 Entry the first. - 2020-08-31 14:32 A second entry in what I hope to be a long series. - """ - - Examples: Configs - | config | - | basic_onefile | - # | basic_folder | @todo - # | basic_dayone | @todo - - Scenario Outline: Delete flag with -from search operator only deletes entries since that date - Given we use the config ".yaml" - When we run "jrnl --delete -from 2020-09-01" and enter - """ - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-29 11:11 Entry the first. - 2020-08-31 14:32 A second entry in what I hope to be a long series. - """ - - Examples: Configs - | config | - | basic_onefile | - # | basic_folder | @todo - # | basic_dayone | @todo - - Scenario Outline: Delete flag with -to only deletes entries up to specified date - Given we use the config ".yaml" - When we run "jrnl --delete -to 2020-08-31" and enter - """ - Y - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-09-24 09:14 The third entry finally after weeks without writing. - """ - - Examples: Configs - | config | - | basic_onefile | - # | basic_folder | @todo - # | basic_dayone | @todo - - - Scenario Outline: Delete flag with -starred only deletes starred entries - Given we use the config ".yaml" - When we run "jrnl --delete -starred" and enter - """ - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-29 11:11 Entry the first. - 2020-09-24 09:14 The third entry finally after weeks without writing. - """ - - Examples: Configs - | config | - | basic_onefile | - # | basic_folder | @todo - # | basic_dayone | @todo - - Scenario Outline: Delete flag with -contains only entries containing expression - Given we use the config ".yaml" - When we run "jrnl --delete -contains dignissim" and enter - """ - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-31 14:32 A second entry in what I hope to be a long series. - 2020-09-24 09:14 The third entry finally after weeks without writing. - """ - - Examples: Configs - | config | - | basic_onefile | - # | basic_folder | @todo - # | basic_dayone | @todo - + | config_file | + | basic_onefile.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | \ No newline at end of file diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 4933a3eb..2f81cd02 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -46,6 +46,10 @@ def toml_version(working_dir): pyproject_contents = toml.load(pyproject) return pyproject_contents["tool"]["poetry"]["version"] +@fixture +def password(): + return '' + @fixture def command(): @@ -56,7 +60,6 @@ def command(): def user_input(): return '' - # ----- STEPS ----- # @given(parse('we use the config "{config_file}"'), target_fixture="config_path") @given('we use the config ""', target_fixture="config_path") @@ -85,11 +88,17 @@ def we_use_the_config(config_file, temp_dir, working_dir): return config_dest +@given(parse('we use the password "{pw}" if prompted'), target_fixture="password") +def use_password_forever(pw): + return pw + + @when(parse('we run "jrnl {command}"')) @when('we run "jrnl "') @when('we run "jrnl"') @when(parse('we run "jrnl" and enter "{user_input}"')) -def we_run(command, config_path, user_input, cli_run, capsys): +@when(parse('we run "jrnl {command}" and enter\n{user_input}')) +def we_run(command, config_path, user_input, cli_run, capsys, password): args = split_args(command) status = 0 @@ -97,7 +106,9 @@ def we_run(command, config_path, user_input, cli_run, capsys): # see: https://github.com/psf/black/issues/664 with \ patch("sys.argv", ['jrnl'] + args), \ - patch("sys.stdin.read", return_value=user_input) as mock_read, \ + patch("sys.stdin.read", side_effect=user_input.splitlines()) as mock_read, \ + patch("builtins.input", side_effect=user_input.splitlines()) as mock_read, \ + patch("getpass.getpass", side_effect=password.splitlines()) as mock_getpass, \ patch("jrnl.install.get_config_path", return_value=config_path), \ patch("jrnl.config.get_config_path", return_value=config_path) \ : # @TODO: single point of truth for get_config_path (move from all calls from install to config) diff --git a/tests/step_defs/test_features.py b/tests/step_defs/test_features.py index 5426d0c0..6afd5c84 100644 --- a/tests/step_defs/test_features.py +++ b/tests/step_defs/test_features.py @@ -3,7 +3,7 @@ from pytest_bdd import scenarios scenarios("../features/build.feature") scenarios("../features/core.feature") scenarios("../features/datetime.feature") -# scenarios("../features/delete.feature") +scenarios("../features/delete.feature") # scenarios("../features/encrypt.feature") # scenarios("../features/file_storage.feature") # scenarios("../features/format.feature") From 40a1a871cbed2f6afd520aaa464e347a4d2dc37f Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Tue, 23 Feb 2021 20:10:19 -0800 Subject: [PATCH 108/215] Migrate the rest of the delete tests from behave to pytest bdd Co-authored-by: Jonathan Wren --- tests/features/delete.feature | 135 +++++++++++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 3 deletions(-) diff --git a/tests/features/delete.feature b/tests/features/delete.feature index 0613c826..f46ef866 100644 --- a/tests/features/delete.feature +++ b/tests/features/delete.feature @@ -19,7 +19,8 @@ Feature: Delete entries from journal | basic_encrypted.yaml | # | basic_folder.yaml | @todo # | basic_dayone.yaml | @todo - + + Scenario Outline: Backing out of interactive delete does not change journal Given we use the config "" When we run "jrnl --delete -n 1" and enter @@ -36,7 +37,7 @@ Feature: Delete entries from journal | basic_folder.yaml | | basic_dayone.yaml | - + Scenario Outline: Delete flag with nonsense input deletes nothing (issue #932) Given we use the config "" When we run "jrnl --delete asdfasdf" @@ -50,4 +51,132 @@ Feature: Delete entries from journal | config_file | | basic_onefile.yaml | | basic_folder.yaml | - | basic_dayone.yaml | \ No newline at end of file + | basic_dayone.yaml | + + + Scenario Outline: Delete flag with tag only deletes tagged entries + Given we use the config "" + When we run "jrnl --delete @ipsum" and enter + Y + When we run "jrnl -99 --short" + Then the output should be + 2020-08-31 14:32 A second entry in what I hope to be a long series. + 2020-09-24 09:14 The third entry finally after weeks without writing. + + Examples: Configs + | config_file | + | basic_onefile.yaml | + # | basic_folder.yaml | @todo + # | basic_dayone.yaml | @todo + + + Scenario Outline: Delete flag with multiple tags deletes all entries matching any of the tags + Given we use the config "" + When we run "jrnl --delete @ipsum @tagthree" and enter + Y + Y + When we run "jrnl -99 --short" + Then the output should be + 2020-08-31 14:32 A second entry in what I hope to be a long series. + + Examples: Configs + | config_file | + | basic_onefile.yaml | + # | basic_folder.yaml | @todo + # | basic_dayone.yaml | @todo + + + Scenario Outline: Delete flag with -and deletes boolean AND of tagged entries + Given we use the config "" + When we run "jrnl --delete -and @tagone @tagtwo" and enter + Y + When we run "jrnl -99 --short" + Then the output should be + 2020-08-31 14:32 A second entry in what I hope to be a long series. + 2020-09-24 09:14 The third entry finally after weeks without writing. + + Examples: Configs + | config_file | + | basic_onefile.yaml | + # | basic_folder.yaml | @todo + # | basic_dayone.yaml | @todo + + + Scenario Outline: Delete flag with -not does not delete entries from given tag + Given we use the config "" + When we run "jrnl --delete @tagone -not @ipsum" and enter + Y + When we run "jrnl -99 --short" + Then the output should be + 2020-08-29 11:11 Entry the first. + 2020-08-31 14:32 A second entry in what I hope to be a long series. + + Examples: Configs + | config_file | + | basic_onefile.yaml | + # | basic_folder.yaml | @todo + # | basic_dayone.yaml | @todo + + + Scenario Outline: Delete flag with -from search operator only deletes entries since that date + Given we use the config "" + When we run "jrnl --delete -from 2020-09-01" and enter + Y + When we run "jrnl -99 --short" + Then the output should be + 2020-08-29 11:11 Entry the first. + 2020-08-31 14:32 A second entry in what I hope to be a long series. + + Examples: Configs + | config_file | + | basic_onefile.yaml | + # | basic_folder.yaml | @todo + # | basic_dayone.yaml | @todo + + + Scenario Outline: Delete flag with -to only deletes entries up to specified date + Given we use the config "" + When we run "jrnl --delete -to 2020-08-31" and enter + Y + Y + When we run "jrnl -99 --short" + Then the output should be + 2020-09-24 09:14 The third entry finally after weeks without writing. + + Examples: Configs + | config_file | + | basic_onefile.yaml | + # | basic_folder.yaml | @todo + # | basic_dayone.yaml | @todo + + + Scenario Outline: Delete flag with -starred only deletes starred entries + Given we use the config "" + When we run "jrnl --delete -starred" and enter + Y + When we run "jrnl -99 --short" + Then the output should be + 2020-08-29 11:11 Entry the first. + 2020-09-24 09:14 The third entry finally after weeks without writing. + + Examples: Configs + | config_file | + | basic_onefile.yaml | + # | basic_folder.yaml | @todo + # | basic_dayone.yaml | @todo + + + Scenario Outline: Delete flag with -contains only entries containing expression + Given we use the config "" + When we run "jrnl --delete -contains dignissim" and enter + Y + When we run "jrnl -99 --short" + Then the output should be + 2020-08-31 14:32 A second entry in what I hope to be a long series. + 2020-09-24 09:14 The third entry finally after weeks without writing. + + Examples: Configs + | config_file | + | basic_onefile.yaml | + # | basic_folder.yaml | @todo + # | basic_dayone.yaml | @todo From 5ad5bac786e5d0a243c3c6ea0fcc99afd17549d4 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Tue, 23 Feb 2021 20:11:26 -0800 Subject: [PATCH 109/215] Standardize line breaks in datetime tests Co-authored-by: Jonathan Wren --- tests/features/datetime.feature | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/features/datetime.feature b/tests/features/datetime.feature index b0f9d2b0..0a3f5155 100644 --- a/tests/features/datetime.feature +++ b/tests/features/datetime.feature @@ -104,6 +104,7 @@ Feature: Reading and writing to journal with custom date formats | sunday: entry on a sunday | entry on a sunday | sunday at 9am | | sUndAy: entry on a sunday | entry on a sunday | sunday at 9am | + Scenario Outline: Create entry using day of the week as entry date. Given we use the config "simple.yaml" When we run "jrnl " @@ -124,12 +125,14 @@ Feature: Reading and writing to journal with custom date formats | sun: entry on a sunday | entry on a sunday | sunday at 9am | | sUn: entry on a sunday | entry on a sunday | sunday at 9am | + Scenario: Journals with unreadable dates should still be loaded Given we use the config "unreadabledates.yaml" When we run "jrnl -2" Then the output should contain "I've lost track of time." And the output should contain "Time has no meaning." + Scenario: Journals with readable dates AND unreadable dates should still contain all data. Given we use the config "mostlyreadabledates.yaml" When we run "jrnl --short" @@ -138,17 +141,20 @@ Feature: Reading and writing to journal with custom date formats 2019-07-18 14:23 The first entry 2019-07-19 14:23 The second entry + Scenario: Update near-valid dates after journal is edited Given we use the config "mostlyreadabledates.yaml" When we run "jrnl 2222-08-19: I have made it exactly one month into the future." When we run "jrnl -2" Then the output should contain "2019-07-19 14:23 The second entry" + Scenario: Integers in square brackets should not be read as dates Given we use the config "brackets.yaml" When we run "jrnl -1" Then the output should contain "[1] line starting with 1" + # broken still @skip Scenario: Dayone entries without timezone information are interpreted in current timezone @@ -157,6 +163,7 @@ Feature: Reading and writing to journal with custom date formats Then we should get no error And the output should contain "2013-01-17T18:37Z" in the local time + Scenario: Loading entry with ambiguous time stamp in timezone-aware journal (like Dayone) #https://github.com/jrnl-org/jrnl/issues/153 Given we use the config "bug153.yaml" From 921ebdcdd53537741eda33ec945722f823368e20 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 27 Feb 2021 14:10:08 -0800 Subject: [PATCH 110/215] Update mocks in "we run" step Co-authored-by: Micah Jerome Ellison --- tests/step_defs/conftest.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 2f81cd02..031b96bd 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -60,6 +60,7 @@ def command(): def user_input(): return '' + # ----- STEPS ----- # @given(parse('we use the config "{config_file}"'), target_fixture="config_path") @given('we use the config ""', target_fixture="config_path") @@ -106,8 +107,8 @@ def we_run(command, config_path, user_input, cli_run, capsys, password): # see: https://github.com/psf/black/issues/664 with \ patch("sys.argv", ['jrnl'] + args), \ - patch("sys.stdin.read", side_effect=user_input.splitlines()) as mock_read, \ - patch("builtins.input", side_effect=user_input.splitlines()) as mock_read, \ + patch("sys.stdin.read", side_effect=user_input.splitlines()) as mock_stdin, \ + patch("builtins.input", side_effect=user_input.splitlines()) as mock_input, \ patch("getpass.getpass", side_effect=password.splitlines()) as mock_getpass, \ patch("jrnl.install.get_config_path", return_value=config_path), \ patch("jrnl.config.get_config_path", return_value=config_path) \ @@ -118,10 +119,16 @@ def we_run(command, config_path, user_input, cli_run, capsys, password): status = e.code # fmt: on - cli_run["status"] = status captured = capsys.readouterr() + + cli_run["status"] = status cli_run["stdout"] = captured.out cli_run["stderr"] = captured.err + cli_run["mocks"] = { + "stdin": mock_stdin, + "input": mock_input, + "getpass": mock_getpass, + } @then("we should get no error") From 1c78a305354c0fb84ea36c8bd72d5443aea3c226 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Tue, 2 Mar 2021 19:32:02 -0800 Subject: [PATCH 111/215] Fix bug in makefile - Makefile no longer runs on virtual env modules - Update some function names so pyflakes doesn't error Co-authored-by: Micah Jerome Ellison --- Makefile | 2 +- tests/step_defs/conftest.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 1c8a52a6..8130dade 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ format: ## Format files to match style lint: ## Check style with various tools poetry check - poetry run pyflakes . + poetry run pyflakes jrnl tests poetry run black --check --diff . test: lint ## Run unit tests and behave tests diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 031b96bd..6f86124b 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -153,7 +153,7 @@ def output_should_contain(output, cli_run): @then(parse("the output should not contain\n{output}")) @then(parse('the output should not contain "{output}"')) @then('the output should not contain ""') -def output_should_contain(output, cli_run): +def output_should_not_contain(output, cli_run): assert output not in cli_run["stdout"] @@ -169,7 +169,7 @@ def output_should_be(output, cli_run): @then('the output should contain the date ""') -def output_should_contain(output, cli_run): +def output_should_contain_date(output, cli_run): assert output and output in cli_run["stdout"] From fe018ee2412f629f093d41d03023b91f88f0b4c9 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Tue, 2 Mar 2021 20:44:26 -0800 Subject: [PATCH 112/215] Implement test keyrings and add password tests - Implement TestKeyring - Implement NoKeyring - Implement FailedKeyring - Copy in `read_value_from_string` function from old tests (will probably rewrite this later) - Add fixtures for keyrings - Implement "we have a keyring" step - Implement step to check specific config values for tests Co-authored-by: Micah Jerome Ellison --- tests/features/password.feature | 110 +----------------------------- tests/step_defs/conftest.py | 113 +++++++++++++++++++++++++++++-- tests/step_defs/test_features.py | 2 +- 3 files changed, 110 insertions(+), 115 deletions(-) diff --git a/tests/features/password.feature b/tests/features/password.feature index 332ba86e..304f51c5 100644 --- a/tests/features/password.feature +++ b/tests/features/password.feature @@ -4,113 +4,9 @@ Feature: Using the installed keyring Given we use the config "multiple.yaml" And we have a keyring When we run "jrnl simple --encrypt" and enter - """ - sabertooth - sabertooth - y - """ + sabertooth + sabertooth + Y Then the config for journal "simple" should have "encrypt" set to "bool:True" When we run "jrnl simple -n 1" Then the output should contain "2013-06-10 15:40 Life is good" - - Scenario: Encrypt journal with no keyring backend and do not store in keyring - Given we use the config "simple.yaml" - And we do not have a keyring - When we run "jrnl test entry" - And we run "jrnl --encrypt" and enter - """ - password - password - n - """ - Then we should get no error - And we should not see the message "Failed to retrieve keyring" - - Scenario: Encrypt journal with no keyring backend and do store in keyring - Given we use the config "simple.yaml" - And we do not have a keyring - When we run "jrnl test entry" - And we run "jrnl --encrypt" and enter - """ - password - password - y - """ - Then we should get no error - And we should not see the message "Failed to retrieve keyring" - # @todo add step to check contents of keyring - - @todo - Scenario: Open an encrypted journal with wrong password in keyring - # This should ask the user for the password after the keyring fails - - @todo - Scenario: Decrypt journal with password in keyring - - @todo - Scenario: Decrypt journal without a keyring - - Scenario: Encrypt journal when keyring exists but fails - Given we use the config "simple.yaml" - And we have a failed keyring - When we run "jrnl --encrypt" and enter - """ - this password will not be saved in keyring - this password will not be saved in keyring - y - """ - Then we should see the message "Failed to retrieve keyring" - And we should get no error - And we should be prompted for a password - And the config for journal "default" should have "encrypt" set to "bool:True" - - Scenario: Decrypt journal when keyring exists but fails - Given we use the config "encrypted.yaml" - And we have a failed keyring - When we run "jrnl --decrypt" and enter "bad doggie no biscuit" - Then we should see the message "Failed to retrieve keyring" - And we should get no error - And we should be prompted for a password - And we should see the message "Journal decrypted" - And the config for journal "default" should have "encrypt" set to "bool:False" - And the journal should have 2 entries - - Scenario: Open encrypted journal when keyring exists but fails - # This should ask the user for the password after the keyring fails - Given we use the config "encrypted.yaml" - And we have a failed keyring - When we run "jrnl -n 1" and enter "bad doggie no biscuit" - Then we should see the message "Failed to retrieve keyring" - And we should get no error - And we should be prompted for a password - And the output should contain "2013-06-10 15:40 Life is good" - - Scenario: Mistyping your password - Given we use the config "simple.yaml" - When we run "jrnl --encrypt" and enter - """ - swordfish - sordfish - """ - Then we should be prompted for a password - And we should see the message "Passwords did not match" - And the config for journal "default" should not have "encrypt" set - And the journal should have 2 entries - - Scenario: Mistyping your password, then getting it right - Given we use the config "simple.yaml" - When we run "jrnl --encrypt" and enter - """ - swordfish - sordfish - swordfish - swordfish - n - """ - Then we should be prompted for a password - And we should see the message "Passwords did not match" - And we should see the message "Journal encrypted" - And the config for journal "default" should have "encrypt" set to "bool: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" diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 6f86124b..2544c470 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -1,7 +1,12 @@ # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html +import ast import os +from collections import defaultdict +from keyring import backend +from keyring import set_keyring +from keyring import errors import re import shutil import tempfile @@ -16,14 +21,75 @@ import toml from jrnl import __version__ from jrnl.cli import cli +from jrnl.config import load_config from jrnl.os_compat import split_args +class TestKeyring(backend.KeyringBackend): + """A test keyring that just stores its values in a hash""" + + priority = 1 + keys = defaultdict(dict) + + def set_password(self, servicename, username, password): + self.keys[servicename][username] = password + + def get_password(self, servicename, username): + return self.keys[servicename].get(username) + + def delete_password(self, servicename, username): + self.keys[servicename][username] = None + + +class NoKeyring(backend.KeyringBackend): + """A keyring that simulated an environment with no keyring backend.""" + + priority = 2 + keys = defaultdict(dict) + + def set_password(self, servicename, username, password): + raise errors.NoKeyringError + + def get_password(self, servicename, username): + raise errors.NoKeyringError + + def delete_password(self, servicename, username): + raise errors.NoKeyringError + + +class FailedKeyring(backend.KeyringBackend): + """ + A keyring that cannot be retrieved. + """ + + priority = 2 + + def set_password(self, servicename, username, password): + raise errors.KeyringError + + def get_password(self, servicename, username): + raise errors.KeyringError + + def delete_password(self, servicename, username): + raise errors.KeyringError + + # ----- UTILS ----- # def failed_msg(msg, expected, actual): return f"{msg}\nExpected:\n{expected}\n---end---\nActual:\n{actual}\n---end---\n" +def read_value_from_string(string): + if string[0] == "{": + # Handle value being a dictionary + return ast.literal_eval(string) + + # Takes strings like "bool:true" or "int:32" and coerces them into proper type + t, value = string.split(":") + value = {"bool": lambda v: v.lower() == "true", "int": int, "str": str}[t](value) + return value + + # ----- FIXTURES ----- # @fixture def cli_run(): @@ -46,22 +112,38 @@ def toml_version(working_dir): pyproject_contents = toml.load(pyproject) return pyproject_contents["tool"]["poetry"]["version"] + @fixture def password(): - return '' + return "" @fixture def command(): - return '' + return "" @fixture def user_input(): - return '' + return "" + + +@fixture +def keyring(): + set_keyring(NoKeyring()) + + +@fixture +def config_data(config_path): + return load_config(config_path) # ----- STEPS ----- # +@given("we have a keyring", target_fixture="keyring") +def we_have_keyring(): + set_keyring(FailedKeyring()) + + @given(parse('we use the config "{config_file}"'), target_fixture="config_path") @given('we use the config ""', target_fixture="config_path") def we_use_the_config(config_file, temp_dir, working_dir): @@ -99,10 +181,13 @@ def use_password_forever(pw): @when('we run "jrnl"') @when(parse('we run "jrnl" and enter "{user_input}"')) @when(parse('we run "jrnl {command}" and enter\n{user_input}')) -def we_run(command, config_path, user_input, cli_run, capsys, password): +def we_run(command, config_path, user_input, cli_run, capsys, password, keyring): args = split_args(command) status = 0 + if not password and user_input: + password = user_input + # fmt: off # see: https://github.com/psf/black/issues/664 with \ @@ -163,9 +248,9 @@ def output_should_not_contain(output, cli_run): def output_should_be(output, cli_run): actual_out = cli_run["stdout"].strip() output = output.strip() - assert ( - output and output == actual_out - ), failed_msg('Output does not match.', output, actual_out) + assert output and output == actual_out, failed_msg( + "Output does not match.", output, actual_out + ) @then('the output should contain the date ""') @@ -183,3 +268,17 @@ def output_should_contain_version(cli_run, toml_version): def should_see_the_message(text, cli_run): out = cli_run["stderr"] assert text in out, [text, out] + + +@then(parse('the config should have "{key}" set to')) +@then(parse('the config should have "{key}" set to "{value}"')) +@then(parse('the config for journal "{journal}" should have "{key}" set to "{value}"')) +def config_var(config_data, key, value="", journal=None): + value = read_value_from_string(value) + + configuration = config_data + if journal: + configuration = configuration["journals"][journal] + + assert key in configuration + assert configuration[key] == value diff --git a/tests/step_defs/test_features.py b/tests/step_defs/test_features.py index 6afd5c84..0860059b 100644 --- a/tests/step_defs/test_features.py +++ b/tests/step_defs/test_features.py @@ -9,7 +9,7 @@ scenarios("../features/delete.feature") # scenarios("../features/format.feature") # scenarios("../features/import.feature") # scenarios("../features/multiple_journals.feature") -# scenarios("../features/password.feature") +scenarios("../features/password.feature") # scenarios("../features/search.feature") # scenarios("../features/star.feature") # scenarios("../features/tag.feature") From d0f92113f4adb1d66d4f69bac7232c4f153d1b97 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Tue, 2 Mar 2021 20:56:55 -0800 Subject: [PATCH 113/215] Add no keyring encryption test to pytest-bdd Co-authored-by: Micah Jerome Ellison --- tests/features/password.feature | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/features/password.feature b/tests/features/password.feature index 304f51c5..cccb94ab 100644 --- a/tests/features/password.feature +++ b/tests/features/password.feature @@ -10,3 +10,15 @@ Feature: Using the installed keyring Then the config for journal "simple" should have "encrypt" set to "bool:True" When we run "jrnl simple -n 1" Then the output should contain "2013-06-10 15:40 Life is good" + + + Scenario: Encrypt journal with no keyring backend and do not store in keyring + Given we use the config "simple.yaml" + When we run "jrnl test entry" + And we run "jrnl --encrypt" and enter + password + password + n + Then we should get no error + And the output should not contain "Failed to retrieve keyring" + From 6b27126c37a460fffdf375c887db181231d1f91d Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Tue, 2 Mar 2021 21:09:33 -0800 Subject: [PATCH 114/215] Implement password prompt steps in pytest-bdd - Scaffold some tests that will be added later - Add fixtures for journal name and keyring type - Add "we should be prompted for a password" step - Add "we should not be prompted for a password" step Co-authored-by: Micah Jerome Ellison --- tests/features/password.feature | 38 +++++++++++++++++++++++++++++++++ tests/step_defs/conftest.py | 38 +++++++++++++++++++++++++++------ 2 files changed, 69 insertions(+), 7 deletions(-) diff --git a/tests/features/password.feature b/tests/features/password.feature index cccb94ab..c8d885f6 100644 --- a/tests/features/password.feature +++ b/tests/features/password.feature @@ -22,3 +22,41 @@ Feature: Using the installed keyring Then we should get no error And the output should not contain "Failed to retrieve keyring" + + Scenario: Encrypt journal with no keyring backend and do store in keyring + Given we use the config "simple.yaml" + When we run "jrnl test entry" + And we run "jrnl --encrypt" and enter + password + password + y + Then we should get no error + And the output should not contain "Failed to retrieve keyring" + # @todo add step to check contents of keyring + + + @todo + Scenario: Open an encrypted journal with wrong password in keyring + # This should ask the user for the password after the keyring fails + + + @todo + Scenario: Decrypt journal with password in keyring + + + @todo + Scenario: Decrypt journal without a keyring + + + Scenario: Encrypt journal when keyring exists but fails + Given we use the config "simple.yaml" + And we have a failed keyring + When we run "jrnl --encrypt" and enter + this password will not be saved in keyring + this password will not be saved in keyring + y + Then we should see the message "Failed to retrieve keyring" + And we should get no error + And we should be prompted for a password + And the config for journal "default" should have "encrypt" set to "bool:True" + diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 2544c470..e8309b69 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -133,15 +133,28 @@ def keyring(): set_keyring(NoKeyring()) +@fixture +def keyring_type(): + return "default" + + @fixture def config_data(config_path): return load_config(config_path) +@fixture +def journal_name(): + return None + # ----- STEPS ----- # @given("we have a keyring", target_fixture="keyring") -def we_have_keyring(): - set_keyring(FailedKeyring()) +@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") @@ -270,15 +283,26 @@ def should_see_the_message(text, cli_run): assert text in out, [text, out] -@then(parse('the config should have "{key}" set to')) +@then(parse('the config should have "{key}" set to\n{value}')) @then(parse('the config should have "{key}" set to "{value}"')) -@then(parse('the config for journal "{journal}" should have "{key}" set to "{value}"')) -def config_var(config_data, key, value="", journal=None): +@then(parse('the config for journal "{journal_name}" should have "{key}" set to "{value}"')) +def config_var(config_data, key, value, journal_name): value = read_value_from_string(value) configuration = config_data - if journal: - configuration = configuration["journals"][journal] + if journal_name: + configuration = configuration["journals"][journal_name] assert key in configuration assert configuration[key] == value + + +@then("we should be prompted for a password") +def password_was_called(cli_run): + assert cli_run["mocks"]["getpass"].called + + +@then("we should not be prompted for a password") +def password_was_not_called(cli_run): + assert not cli_run["mocks"]["getpass"].called + From 10b604ef8923c05fefaaaf0e641558dcf9b3db8a Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 6 Mar 2021 12:03:05 -0800 Subject: [PATCH 115/215] Add more password tests to pytest-bdd - Fix some input handling in steps (especially for passwords) - Fix some formatting issues Co-authored-by: Micah Jerome Ellison --- tests/features/password.feature | 17 +++++++++++++++++ tests/step_defs/conftest.py | 34 ++++++++++++++++++++++++++------- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/tests/features/password.feature b/tests/features/password.feature index c8d885f6..a5cbb0e1 100644 --- a/tests/features/password.feature +++ b/tests/features/password.feature @@ -60,3 +60,20 @@ Feature: Using the installed keyring And we should be prompted for a password And the config for journal "default" should have "encrypt" set to "bool:True" + + Scenario: Decrypt journal when keyring exists but fails + Given we use the config "encrypted.yaml" + And we have a failed keyring + And we use the password "bad doggie no biscuit" if prompted + When we run "jrnl --decrypt" + Then the error output should contain "Failed to retrieve keyring" + And we should get no error + And we should be prompted for a password + And we should see the message "Journal decrypted" + And the config for journal "default" should have "encrypt" set to "bool:False" + When we run "jrnl --short" + Then we should not be prompted for a password + And the output should be + 2013-06-09 15:39 My first entry. + 2013-06-10 15:40 Life is good. + diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index e8309b69..c1046ef3 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -147,6 +147,12 @@ def config_data(config_path): def journal_name(): return None + +@fixture +def output_to_error(): + return False + + # ----- STEPS ----- # @given("we have a keyring", target_fixture="keyring") @given(parse("we have a {keyring_type} keyring"), target_fixture="keyring") @@ -198,6 +204,12 @@ def we_run(command, config_path, user_input, cli_run, capsys, password, keyring) args = split_args(command) status = 0 + if user_input: + user_input = user_input.splitlines() + + if password: + password = password.splitlines() + if not password and user_input: password = user_input @@ -205,9 +217,9 @@ def we_run(command, config_path, user_input, cli_run, capsys, password, keyring) # see: https://github.com/psf/black/issues/664 with \ patch("sys.argv", ['jrnl'] + args), \ - patch("sys.stdin.read", side_effect=user_input.splitlines()) as mock_stdin, \ - patch("builtins.input", side_effect=user_input.splitlines()) as mock_input, \ - patch("getpass.getpass", side_effect=password.splitlines()) as mock_getpass, \ + patch("sys.stdin.read", side_effect=user_input) as mock_stdin, \ + patch("builtins.input", side_effect=user_input) as mock_input, \ + patch("getpass.getpass", side_effect=password) as mock_getpass, \ patch("jrnl.install.get_config_path", return_value=config_path), \ patch("jrnl.config.get_config_path", return_value=config_path) \ : # @TODO: single point of truth for get_config_path (move from all calls from install to config) @@ -244,8 +256,13 @@ def output_should_match(regex, cli_run): @then(parse("the output should contain\n{output}")) @then(parse('the output should contain "{output}"')) @then('the output should contain ""') -def output_should_contain(output, cli_run): - assert output and output in cli_run["stdout"] +@then(parse("the {output_to_error} output should contain\n{output}")) +@then(parse('the {output_to_error} output should contain "{output}"')) +def output_should_contain(output, output_to_error, cli_run): + assert output and ( + (output_to_error and output in cli_run["stderr"]) + or (not output_to_error and output in cli_run["stdout"]) + ) @then(parse("the output should not contain\n{output}")) @@ -285,7 +302,11 @@ def should_see_the_message(text, cli_run): @then(parse('the config should have "{key}" set to\n{value}')) @then(parse('the config should have "{key}" set to "{value}"')) -@then(parse('the config for journal "{journal_name}" should have "{key}" set to "{value}"')) +@then( + parse( + 'the config for journal "{journal_name}" should have "{key}" set to "{value}"' + ) +) def config_var(config_data, key, value, journal_name): value = read_value_from_string(value) @@ -305,4 +326,3 @@ def password_was_called(cli_run): @then("we should not be prompted for a password") def password_was_not_called(cli_run): assert not cli_run["mocks"]["getpass"].called - From c76ee8cd4fe2ce73533f11a8657c4501d034a663 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 6 Mar 2021 13:35:42 -0800 Subject: [PATCH 116/215] Add more password tests to pytest-bdd Co-authored-by: Micah Jerome Ellison --- tests/features/password.feature | 12 ++++++++++++ tests/step_defs/conftest.py | 26 +++++++++++++++++--------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/tests/features/password.feature b/tests/features/password.feature index a5cbb0e1..23287b7c 100644 --- a/tests/features/password.feature +++ b/tests/features/password.feature @@ -77,3 +77,15 @@ Feature: Using the installed keyring 2013-06-09 15:39 My first entry. 2013-06-10 15:40 Life is good. + + Scenario: Open encrypted journal when keyring exists but fails + # This should ask the user for the password after the keyring fails + Given we use the config "encrypted.yaml" + And we have a failed keyring + And we use the password "bad doggie no biscuit" if prompted + When we run "jrnl -n 1" + Then we should get no error + And we should be prompted for a password + And the output should contain "Failed to retrieve keyring" + And the output should contain "2013-06-10 15:40 Life is good" + diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index c1046ef3..e15f265f 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -149,8 +149,8 @@ def journal_name(): @fixture -def output_to_error(): - return False +def which_output_stream(): + return None # ----- STEPS ----- # @@ -256,13 +256,21 @@ def output_should_match(regex, cli_run): @then(parse("the output should contain\n{output}")) @then(parse('the output should contain "{output}"')) @then('the output should contain ""') -@then(parse("the {output_to_error} output should contain\n{output}")) -@then(parse('the {output_to_error} output should contain "{output}"')) -def output_should_contain(output, output_to_error, cli_run): - assert output and ( - (output_to_error and output in cli_run["stderr"]) - or (not output_to_error and output in cli_run["stdout"]) - ) +@then(parse("the {which_output_stream} output should contain\n{output}")) +@then(parse('the {which_output_stream} output should contain "{output}"')) +def output_should_contain(output, which_output_stream, cli_run): + assert output + if which_output_stream is None: + assert (output in cli_run["stdout"]) or (output in cli_run["stderr"]) + + elif which_output_stream == "standard": + assert output in cli_run["stdout"] + + elif which_output_stream == "error": + assert output in cli_run["stderr"] + + else: + assert output in cli_run[which_output_stream] @then(parse("the output should not contain\n{output}")) From e720430aa498634dd6c13d58434504a8b9f81eb4 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 20 Mar 2021 15:52:23 -0700 Subject: [PATCH 117/215] Implement "should" and "should not" handling - Handling should and should not like this should reduce the amount of fixtures we need for the test suite - Add more password tests Co-authored-by: Micah Jerome Ellison --- tests/features/password.feature | 14 +++++++++++ tests/step_defs/conftest.py | 42 +++++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/tests/features/password.feature b/tests/features/password.feature index 23287b7c..6cd2d2b6 100644 --- a/tests/features/password.feature +++ b/tests/features/password.feature @@ -89,3 +89,17 @@ Feature: Using the installed keyring And the output should contain "Failed to retrieve keyring" And the output should contain "2013-06-10 15:40 Life is good" + + Scenario: Mistyping your password + Given we use the config "simple.yaml" + When we run "jrnl --encrypt" and enter + swordfish + sordfish + Then we should be prompted for a password + And we should see the message "Passwords did not match" + And the config for journal "default" should not have "encrypt" set + When we run "jrnl --short" + Then the output should be + 2013-06-09 15:39 My first entry. + 2013-06-10 15:40 Life is good. + diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index e15f265f..47aa7882 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -118,11 +118,21 @@ def password(): return "" +@fixture +def str_value(): + return "" + + @fixture def command(): return "" +@fixture +def should_not(): + return False + + @fixture def user_input(): return "" @@ -225,6 +235,9 @@ def we_run(command, config_path, user_input, cli_run, capsys, password, keyring) : # @TODO: single point of truth for get_config_path (move from all calls from install to config) try: cli(args) + except StopIteration: + # This happens when input is expected, but don't have any input left + pass except SystemExit as e: status = e.code # fmt: on @@ -308,22 +321,37 @@ def should_see_the_message(text, cli_run): assert text in out, [text, out] -@then(parse('the config should have "{key}" set to\n{value}')) -@then(parse('the config should have "{key}" set to "{value}"')) +@then(parse('the config should have "{key}" set to\n{str_value}')) +@then(parse('the config should have "{key}" set to "{str_value}"')) @then( parse( - 'the config for journal "{journal_name}" should have "{key}" set to "{value}"' + 'the config for journal "{journal_name}" should have "{key}" set to "{str_value}"' ) ) -def config_var(config_data, key, value, journal_name): - value = read_value_from_string(value) +@then(parse('the config should {should_not} have "{key}" set')) +@then(parse('the config should {should_not} have "{key}" set')) +@then( + parse( + 'the config for journal "{journal_name}" should {should_not} have "{key}" set' + ) +) +def config_var(config_data, key, str_value, journal_name, should_not): + str_value = read_value_from_string(str_value) if len(str_value) else str_value configuration = config_data if journal_name: configuration = configuration["journals"][journal_name] - assert key in configuration - assert configuration[key] == value + # is the config a string? + # @todo this should probably be a function + if type(configuration) is str: + configuration = {"journal": configuration} + + if should_not: + assert key not in configuration + else: + assert key in configuration + assert configuration[key] == str_value @then("we should be prompted for a password") From 3d3bd917009cde7d29e558e8108a72114269d55d Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 3 Apr 2021 14:06:53 -0700 Subject: [PATCH 118/215] Expand "we run" step to handling input better - Use regex parser in pytest-bdd to support "we run" steps that also have user input ("and enter") Co-authored-by: Micah Jerome Ellison --- tests/features/password.feature | 17 +++++++++++++++++ tests/step_defs/conftest.py | 6 ++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/tests/features/password.feature b/tests/features/password.feature index 6cd2d2b6..d3116fed 100644 --- a/tests/features/password.feature +++ b/tests/features/password.feature @@ -103,3 +103,20 @@ Feature: Using the installed keyring 2013-06-09 15:39 My first entry. 2013-06-10 15:40 Life is good. + + Scenario: Mistyping your password, then getting it right + Given we use the config "simple.yaml" + When we run "jrnl --encrypt" and enter + swordfish + sordfish + swordfish + swordfish + n + Then we should be prompted for a password + And we should see the message "Passwords did not match" + And we should see the message "Journal encrypted" + And the config for journal "default" should have "encrypt" set to "bool:True" + When we run "jrnl -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" + diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 47aa7882..dd08502f 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -16,6 +16,7 @@ from pytest_bdd import given from pytest_bdd import then from pytest_bdd import when from pytest_bdd.parsers import parse +from pytest_bdd import parsers from pytest import fixture import toml @@ -205,11 +206,12 @@ def use_password_forever(pw): return pw +@when(parse('we run "jrnl {command}" and enter\n{user_input}')) +@when(parsers.re('we run "jrnl (?P[^"]+)" and enter "(?P[^"]+)"')) @when(parse('we run "jrnl {command}"')) +@when(parse('we run "jrnl" and enter "{user_input}"')) @when('we run "jrnl "') @when('we run "jrnl"') -@when(parse('we run "jrnl" and enter "{user_input}"')) -@when(parse('we run "jrnl {command}" and enter\n{user_input}')) def we_run(command, config_path, user_input, cli_run, capsys, password, keyring): args = split_args(command) status = 0 From e2bb8cf0deb9f3e5fdfb482006bd45c280031c4c Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 3 Apr 2021 14:15:43 -0700 Subject: [PATCH 119/215] Add encryption test to pytest-bdd - Clean up some formatting Co-authored-by: Micah Jerome Ellison --- tests/features/encrypt.feature | 21 ++++++++++++++------- tests/step_defs/test_features.py | 2 +- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/tests/features/encrypt.feature b/tests/features/encrypt.feature index f2d0a62f..b9b9ff5a 100644 --- a/tests/features/encrypt.feature +++ b/tests/features/encrypt.feature @@ -5,7 +5,11 @@ Feature: Encrypting and decrypting journals When we run "jrnl --decrypt" and enter "bad doggie no biscuit" Then the config for journal "default" should have "encrypt" set to "bool:False" And we should see the message "Journal decrypted" - And the journal should have 2 entries + When we run "jrnl -99 --short" + Then the output should be + 2013-06-09 15:39 My first entry. + 2013-06-10 15:40 Life is good. + @todo Scenario: Trying to decrypt an already unencrypted journal @@ -13,20 +17,23 @@ Feature: Encrypting and decrypting journals Given we use the config "simple.yaml" When we run "jrnl --decrypt" Then the config for journal "default" should have "encrypt" set to "bool:False" - And the journal should have 2 entries + When we run "jrnl -99 --short" + Then the output should be + 2013-06-09 15:39 My first entry. + 2013-06-10 15:40 Life is good. + @todo Scenario: Trying to encrypt an already encrypted journal # This should warn the user that the journal is already encrypted + Scenario: Encrypting a journal Given we use the config "simple.yaml" When we run "jrnl --encrypt" and enter - """ - swordfish - swordfish - n - """ + swordfish + swordfish + n Then we should see the message "Journal encrypted" And the config for journal "default" should have "encrypt" set to "bool:True" When we run "jrnl -n 1" and enter "swordfish" diff --git a/tests/step_defs/test_features.py b/tests/step_defs/test_features.py index 0860059b..d04928be 100644 --- a/tests/step_defs/test_features.py +++ b/tests/step_defs/test_features.py @@ -4,7 +4,7 @@ scenarios("../features/build.feature") scenarios("../features/core.feature") scenarios("../features/datetime.feature") scenarios("../features/delete.feature") -# scenarios("../features/encrypt.feature") +scenarios("../features/encrypt.feature") # scenarios("../features/file_storage.feature") # scenarios("../features/format.feature") # scenarios("../features/import.feature") From b8c7a7c7e560d7720bb4fcfb3583b080622fbf51 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 3 Apr 2021 15:51:19 -0700 Subject: [PATCH 120/215] Add format tests to pytest-bdd - Implement cache dir fixture and step - Implement various steps to check the cache directory (files contained, etc) Co-authored-by: Micah Jerome Ellison --- tests/features/format.feature | 892 +++++++++++++++---------------- tests/step_defs/conftest.py | 123 ++++- tests/step_defs/test_features.py | 2 +- 3 files changed, 557 insertions(+), 460 deletions(-) diff --git a/tests/features/format.feature b/tests/features/format.feature index 4981f685..2ac5cdf2 100644 --- a/tests/features/format.feature +++ b/tests/features/format.feature @@ -1,7 +1,7 @@ Feature: Custom formats Scenario Outline: JSON format - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl --format json" Then we should get no error @@ -16,11 +16,11 @@ Feature: Custom formats And entry 3 should have an array "tags" with 2 elements Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario: Exporting dayone to json Given we use the config "dayone.yaml" @@ -30,43 +30,41 @@ Feature: Custom formats And the json output should contain entries.0.uuid = "4BB1F46946AD439996C9B59DE7C4DDC1" Scenario Outline: Printing a journal that has multiline entries with tags - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl -n 1 @ipsum" Then we should get no error And the output should be - """ - 2020-08-29 11:11 Entry the first. - | Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada - | quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus - | pellentesque - | augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu - | consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In - | commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget - | venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. - | - | Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo - | ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse - | potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget - | molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus - | hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis - | feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum - | urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. - | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget - | velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac - | porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per - | conubia nostra, per inceptos himenaeos. - """ + 2020-08-29 11:11 Entry the first. + | Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada + | quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus + | pellentesque + | augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu + | consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In + | commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget + | venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. + | + | Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo + | ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse + | potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget + | molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus + | hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis + | feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum + | urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. + | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget + | velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac + | porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per + | conubia nostra, per inceptos himenaeos. Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Exporting using filters should only export parts of the journal - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl -until 'August 2020' --format json" Then the output should be parsable as json @@ -80,392 +78,21 @@ Feature: Custom formats And entry 2 should have an array "tags" with 1 elements Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Exporting using custom templates - Given we use the config ".yaml" + Given we use the config "" And we load template "sample.template" And we use the password "test" if prompted When we run "jrnl -1 --format sample" Then the output should be - """ - The third entry finally after weeks without writing. - ---------------------------------------------------- + The third entry finally after weeks without writing. + ---------------------------------------------------- - I'm so excited about emojis. 💯 🎶 💩 - - Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. - Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla - eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis - dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. - Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis - vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. - Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at - ante eget fringilla. @tagthree and also @tagone - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario Outline: Increasing Headings on Markdown export - Given we use the config ".yaml" - And we use the password "test" if prompted - When we open the editor and append - """ - [2020-10-14 13:23] Heading Test - - H1-1 - = - - H1-2 - === - - H1-3 - ============================ - - H2-1 - - - - H2-2 - --- - - H2-3 - ---------------------------------- - - Horizontal Rules (ignore) - - --- - - === - - # ATX H1 - - ## ATX H2 - - ### ATX H3 - - #### ATX H4 - - ##### ATX H5 - - ###### ATX H6 - - Stuff - - More stuff - more stuff again - """ - Then we flush the output - When we run "jrnl -1 --export markdown" - Then the output should be - """ - # 2020 - - ## October - - ### 2020-10-14 13:23 Heading Test - - #### H1-1 - - #### H1-2 - - #### H1-3 - - ##### H2-1 - - ##### H2-2 - - ##### H2-3 - - Horizontal Rules (ignore) - - --- - - === - - #### ATX H1 - - ##### ATX H2 - - ###### ATX H3 - - ####### ATX H4 - - ######## ATX H5 - - ######### ATX H6 - - Stuff - - More stuff - more stuff again - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - # | basic_dayone | @todo - - Scenario Outline: Add a blank line to Markdown export if there isn't one already - # https://github.com/jrnl-org/jrnl/issues/768 - # https://github.com/jrnl-org/jrnl/issues/881 - Given we use the config ".yaml" - And we use the password "test" if prompted - When we open the editor and append - """ - [2020-10-29 11:11] First entry. - [2020-10-29 11:11] Second entry. - [2020-10-29 11:13] Third entry. - """ - Then we flush the output - When we run "jrnl -3 --format markdown" - Then the output should be - """ - # 2020 - - ## October - - ### 2020-10-29 11:11 First entry. - - - ### 2020-10-29 11:11 Second entry. - - - ### 2020-10-29 11:13 Third entry. - - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - # | basic_dayone | @todo - - @skip - Scenario Outline: Exporting to XML - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl --export xml" - Then the output should be a valid XML string - And "entries" node in the xml output should have 3 elements - And "tags" in the xml output should contain ["@ipsum", "@tagone", "@tagtwo", "@tagthree"] - And there should be 10 "tag" elements - - Examples: configs - | config | - # | basic_onefile | @todo - # | basic_encrypted | @todo - # | basic_folder | @todo - # | basic_dayone | @todo - - Scenario: Exporting to XML - Given we use the config "tags.yaml" - And we use the password "test" if prompted - When we run "jrnl --export xml" - Then the output should be a valid XML string - And "entries" node in the xml output should have 2 elements - And "tags" in the xml output should contain ["@idea", "@journal", "@dan"] - And there should be 7 "tag" elements - - Scenario Outline: Exporting tags - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl --export tags" - Then the output should be - """ - @tagtwo : 2 - @tagone : 2 - @tagthree : 1 - @ipsum : 1 - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - @todo - Scenario Outline: Exporting fancy - # Needs better emoji support - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl --export fancy" - Then the output should be - """ - ┎──────────────────────────────────────────────────────────────╮2020-08-29 11:11 - ┃ Entry the first. ╘═══════════════╕ - ┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ - ┃ Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada │ - ┃ quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus │ - ┃ pellentesque │ - ┃ augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu │ - ┃ consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In │ - ┃ commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget │ - ┃ venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. │ - ┃ │ - ┃ Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo │ - ┃ ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. │ - ┃ Suspendisse │ - ┃ potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas │ - ┃ eget │ - ┃ molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed │ - ┃ lectus │ - ┃ hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis │ - ┃ feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, │ - ┃ vestibulum │ - ┃ urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod │ - ┃ enim. │ - ┃ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget │ - ┃ velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac │ - ┃ porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per │ - ┃ conubia nostra, per inceptos himenaeos. │ - ┖──────────────────────────────────────────────────────────────────────────────┘ - ┎──────────────────────────────────────────────────────────────╮2020-08-31 14:32 - ┃ A second entry in what I hope to be a long series. ╘═══════════════╕ - ┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ - ┃ Sed sit amet metus et sapien feugiat elementum. Aliquam bibendum lobortis │ - ┃ leo │ - ┃ vitae tempus. Donec eleifend nec mi non volutpat. Lorem ipsum dolor sit │ - ┃ amet, │ - ┃ consectetur adipiscing elit. Praesent ut sodales libero. Maecenas nisl │ - ┃ lorem, │ - ┃ vestibulum in tempus sit amet, fermentum ut arcu. Donec vel vestibulum │ - ┃ lectus, │ - ┃ eget pretium enim. Maecenas diam nunc, imperdiet vitae pharetra sed, pretium │ - ┃ id │ - ┃ lectus. Donec eu metus et turpis tempor tristique ac non ex. In tellus arcu, │ - ┃ egestas at efficitur et, ultrices vel est. Sed commodo et nibh non │ - ┃ elementum. │ - ┃ Mauris tempus vitae neque vel viverra. @tagtwo all by its lonesome. │ - ┃ │ - ┃ Nulla mattis elementum magna, viverra pretium dui fermentum et. Cras vel │ - ┃ vestibulum odio. Quisque sit amet turpis et urna finibus maximus. Interdum │ - ┃ et │ - ┃ malesuada fames ac ante ipsum primis in faucibus. Fusce porttitor iaculis │ - ┃ sem, │ - ┃ non dictum ipsum varius nec. Nulla eu erat at risus gravida blandit non vel │ - ┃ ante. Nam egestas ipsum leo, eu ultricies ipsum tincidunt vel. Morbi a │ - ┃ commodo │ - ┃ eros. │ - ┃ │ - ┃ Nullam dictum, nisl ac varius tempus, ex tortor fermentum nisl, non │ - ┃ tempus dolor neque a lorem. Suspendisse a faucibus ex, vel ornare tortor. │ - ┃ Maecenas tincidunt id felis quis semper. Pellentesque enim libero, fermentum │ - ┃ quis metus id, rhoncus euismod magna. Nulla finibus velit eu purus bibendum │ - ┃ interdum. Integer id justo dui. Integer eu tellus in turpis bibendum │ - ┃ blandit. │ - ┃ Quisque auctor lacinia consectetur. │ - ┖──────────────────────────────────────────────────────────────────────────────┘ - ┎──────────────────────────────────────────────────────────────╮2020-09-24 09:14 - ┃ The third entry finally after weeks without writing. ╘═══════════════╕ - ┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ - ┃ I'm so excited about emojis. 💯 🎶 💩 │ - ┃ │ - ┃ Donec semper pellentesque iaculis. Nullam cursus et justo sit amet │ - ┃ venenatis. │ - ┃ Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. │ - ┃ Nulla │ - ┃ eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis │ - ┃ dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh │ - ┃ malesuada. │ - ┃ Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis │ - ┃ vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan │ - ┃ justo. │ - ┃ Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at │ - ┃ ante eget fringilla. @tagthree and also @tagone │ - ┖──────────────────────────────────────────────────────────────────────────────┘ - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - @skip_win - Scenario Outline: Export to yaml - Given we use the config ".yaml" - And we use the password "test" if prompted - And we create a cache directory - When we run "jrnl --export yaml -o {cache_dir}" - Then the cache should contain the files - """ - 2020-08-29_entry-the-first.md - 2020-08-31_a-second-entry-in-what-i-hope-to-be-a-long-series.md - 2020-09-24_the-third-entry-finally-after-weeks-without-writing.md - """ - And the content of file "2020-08-29_entry-the-first.md" in the cache should be - """ - --- - title: Entry the first. - date: 2020-08-29 11:11 - starred: False - tags: tagone, ipsum, tagtwo - body: | - Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada - quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque - augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu - consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In - commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget - venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. - - Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo - ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse - potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget - molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus - hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis - feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum - urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget - velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac - porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per - conubia nostra, per inceptos himenaeos. - ... - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - # | basic_dayone | - - @skip_win # @todo YAML exporter does not correctly export emoji on Windows - Scenario Outline: Add a blank line to YAML export if there isn't one already - # https://github.com/jrnl-org/jrnl/issues/768 - # https://github.com/jrnl-org/jrnl/issues/881 - Given we use the config ".yaml" - And we use the password "test" if prompted - And we create a cache directory - When we run "jrnl --export yaml -o {cache_dir}" - Then the cache should contain the files - """ - 2020-08-29_entry-the-first.md - 2020-08-31_a-second-entry-in-what-i-hope-to-be-a-long-series.md - 2020-09-24_the-third-entry-finally-after-weeks-without-writing.md - """ - And the content of file "2020-09-24_the-third-entry-finally-after-weeks-without-writing.md" in the cache should be - """ - --- - title: The third entry finally after weeks without writing. - date: 2020-09-24 09:14 - starred: False - tags: tagone, tagthree - body: | I'm so excited about emojis. 💯 🎶 💩 Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. @@ -475,16 +102,373 @@ Feature: Custom formats Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at - ante eget fringilla. @tagthree and also @tagone - ... - """ + ante eget fringilla. @tagthree and also @tagone Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - # | basic_dayone | @todo + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | + + Scenario Outline: Increasing Headings on Markdown export + Given we use the config "" + And we use the password "test" if prompted + When we open the editor and append + [2020-10-14 13:23] Heading Test + + H1-1 + = + + H1-2 + === + + H1-3 + ============================ + + H2-1 + - + + H2-2 + --- + + H2-3 + ---------------------------------- + + Horizontal Rules (ignore) + + --- + + === + + # ATX H1 + + ## ATX H2 + + ### ATX H3 + + #### ATX H4 + + ##### ATX H5 + + ###### ATX H6 + + Stuff + + More stuff + more stuff again + Then we flush the output + When we run "jrnl -1 --export markdown" + Then the output should be + # 2020 + + ## October + + ### 2020-10-14 13:23 Heading Test + + #### H1-1 + + #### H1-2 + + #### H1-3 + + ##### H2-1 + + ##### H2-2 + + ##### H2-3 + + Horizontal Rules (ignore) + + --- + + === + + #### ATX H1 + + ##### ATX H2 + + ###### ATX H3 + + ####### ATX H4 + + ######## ATX H5 + + ######### ATX H6 + + Stuff + + More stuff + more stuff again + + Examples: configs + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + # | basic_dayone.yaml | @todo + + Scenario Outline: Add a blank line to Markdown export if there isn't one already + # https://github.com/jrnl-org/jrnl/issues/768 + # https://github.com/jrnl-org/jrnl/issues/881 + Given we use the config "" + And we use the password "test" if prompted + When we open the editor and append + [2020-10-29 11:11] First entry. + [2020-10-29 11:11] Second entry. + [2020-10-29 11:13] Third entry. + Then we flush the output + When we run "jrnl -3 --format markdown" + Then the output should be + # 2020 + + ## October + + ### 2020-10-29 11:11 First entry. + + + ### 2020-10-29 11:11 Second entry. + + + ### 2020-10-29 11:13 Third entry. + + + Examples: configs + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + # | basic_dayone.yaml | @todo + + @skip + Scenario Outline: Exporting to XML + Given we use the config "" + And we use the password "test" if prompted + When we run "jrnl --export xml" + Then the output should be a valid XML string + And "entries" node in the xml output should have 3 elements + And "tags" in the xml output should contain + @ipsum + @tagone + @tagtwo + @tagthree + And there should be 10 "tag" elements + + Examples: configs + | config_file | + # | basic_onefile.yaml | @todo + # | basic_encrypted.yaml | @todo + # | basic_folder.yaml | @todo + # | basic_dayone.yaml | @todo + + Scenario: Exporting to XML + Given we use the config "tags.yaml" + And we use the password "test" if prompted + When we run "jrnl --export xml" + Then the output should be a valid XML string + And "entries" node in the xml output should have 2 elements + And "tags" in the xml output should contain + @idea + @journal + @dan + And there should be 7 "tag" elements + + Scenario Outline: Exporting tags + Given we use the config "" + And we use the password "test" if prompted + When we run "jrnl --export tags" + Then the output should be + @tagtwo : 2 + @tagone : 2 + @tagthree : 1 + @ipsum : 1 + + 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 + Given we use the config "" + And we use the password "test" if prompted + When we run "jrnl --export fancy" + Then the output should be + ┎──────────────────────────────────────────────────────────────╮2020-08-29 11:11 + ┃ Entry the first. ╘═══════════════╕ + ┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ + ┃ Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada │ + ┃ quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus │ + ┃ pellentesque │ + ┃ augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu │ + ┃ consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In │ + ┃ commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget │ + ┃ venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. │ + ┃ │ + ┃ Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo │ + ┃ ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. │ + ┃ Suspendisse │ + ┃ potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas │ + ┃ eget │ + ┃ molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed │ + ┃ lectus │ + ┃ hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis │ + ┃ feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, │ + ┃ vestibulum │ + ┃ urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod │ + ┃ enim. │ + ┃ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget │ + ┃ velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac │ + ┃ porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per │ + ┃ conubia nostra, per inceptos himenaeos. │ + ┖──────────────────────────────────────────────────────────────────────────────┘ + ┎──────────────────────────────────────────────────────────────╮2020-08-31 14:32 + ┃ A second entry in what I hope to be a long series. ╘═══════════════╕ + ┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ + ┃ Sed sit amet metus et sapien feugiat elementum. Aliquam bibendum lobortis │ + ┃ leo │ + ┃ vitae tempus. Donec eleifend nec mi non volutpat. Lorem ipsum dolor sit │ + ┃ amet, │ + ┃ consectetur adipiscing elit. Praesent ut sodales libero. Maecenas nisl │ + ┃ lorem, │ + ┃ vestibulum in tempus sit amet, fermentum ut arcu. Donec vel vestibulum │ + ┃ lectus, │ + ┃ eget pretium enim. Maecenas diam nunc, imperdiet vitae pharetra sed, pretium │ + ┃ id │ + ┃ lectus. Donec eu metus et turpis tempor tristique ac non ex. In tellus arcu, │ + ┃ egestas at efficitur et, ultrices vel est. Sed commodo et nibh non │ + ┃ elementum. │ + ┃ Mauris tempus vitae neque vel viverra. @tagtwo all by its lonesome. │ + ┃ │ + ┃ Nulla mattis elementum magna, viverra pretium dui fermentum et. Cras vel │ + ┃ vestibulum odio. Quisque sit amet turpis et urna finibus maximus. Interdum │ + ┃ et │ + ┃ malesuada fames ac ante ipsum primis in faucibus. Fusce porttitor iaculis │ + ┃ sem, │ + ┃ non dictum ipsum varius nec. Nulla eu erat at risus gravida blandit non vel │ + ┃ ante. Nam egestas ipsum leo, eu ultricies ipsum tincidunt vel. Morbi a │ + ┃ commodo │ + ┃ eros. │ + ┃ │ + ┃ Nullam dictum, nisl ac varius tempus, ex tortor fermentum nisl, non │ + ┃ tempus dolor neque a lorem. Suspendisse a faucibus ex, vel ornare tortor. │ + ┃ Maecenas tincidunt id felis quis semper. Pellentesque enim libero, fermentum │ + ┃ quis metus id, rhoncus euismod magna. Nulla finibus velit eu purus bibendum │ + ┃ interdum. Integer id justo dui. Integer eu tellus in turpis bibendum │ + ┃ blandit. │ + ┃ Quisque auctor lacinia consectetur. │ + ┖──────────────────────────────────────────────────────────────────────────────┘ + ┎──────────────────────────────────────────────────────────────╮2020-09-24 09:14 + ┃ The third entry finally after weeks without writing. ╘═══════════════╕ + ┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ + ┃ I'm so excited about emojis. 💯 🎶 💩 │ + ┃ │ + ┃ Donec semper pellentesque iaculis. Nullam cursus et justo sit amet │ + ┃ venenatis. │ + ┃ Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. │ + ┃ Nulla │ + ┃ eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis │ + ┃ dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh │ + ┃ malesuada. │ + ┃ Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis │ + ┃ vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan │ + ┃ justo. │ + ┃ Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at │ + ┃ ante eget fringilla. @tagthree and also @tagone │ + ┖──────────────────────────────────────────────────────────────────────────────┘ + + Examples: configs + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | + + @skip_win + Scenario Outline: Export to yaml + Given we use the config "" + And we use the password "test" if prompted + And we create a cache directory + When we run "jrnl --format yaml --file {cache_dir}" + Then the cache directory should contain the files + 2020-08-29_entry-the-first.md + 2020-08-31_a-second-entry-in-what-i-hope-to-be-a-long-series.md + 2020-09-24_the-third-entry-finally-after-weeks-without-writing.md + + And the content of file "2020-08-29_entry-the-first.md" in the cache should be + --- + title: Entry the first. + date: 2020-08-29 11:11 + starred: False + tags: tagone, ipsum, tagtwo + body: | + Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada + quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque + augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu + consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In + commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget + venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. + + Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo + ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse + potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget + molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus + hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis + feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum + urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget + velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac + porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per + conubia nostra, per inceptos himenaeos. + ... + + Examples: configs + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + # | basic_dayone.yaml | + + @skip_win # @todo YAML exporter does not correctly export emoji on Windows + Scenario Outline: Add a blank line to YAML export if there isn't one already + # https://github.com/jrnl-org/jrnl/issues/768 + # https://github.com/jrnl-org/jrnl/issues/881 + Given we use the config "" + And we use the password "test" if prompted + And we create a cache directory + When we run "jrnl --export yaml -o {cache_dir}" + Then the cache should contain the files + 2020-08-29_entry-the-first.md + 2020-08-31_a-second-entry-in-what-i-hope-to-be-a-long-series.md + 2020-09-24_the-third-entry-finally-after-weeks-without-writing.md + And the content of file "2020-09-24_the-third-entry-finally-after-weeks-without-writing.md" in the cache should be + --- + title: The third entry finally after weeks without writing. + date: 2020-09-24 09:14 + starred: False + tags: tagone, tagthree + body: | + I'm so excited about emojis. 💯 🎶 💩 + + Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. + Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla + eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis + dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. + Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis + vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. + Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at + ante eget fringilla. @tagthree and also @tagone + ... + + Examples: configs + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + # | basic_dayone.yaml | @todo Scenario: Empty DayOne entry bodies should not error # https://github.com/jrnl-org/jrnl/issues/780 @@ -493,36 +477,35 @@ Feature: Custom formats Then we should get no error Scenario Outline: --short displays the short version of entries (only the title) - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl -on 2020-08-31 --short" Then the output should be "2020-08-31 14:32 A second entry in what I hope to be a long series." Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: -s displays the short version of entries (only the title) - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl -on 2020-08-31 -s" Then the output should be "2020-08-31 14:32 A second entry in what I hope to be a long series." Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario: Markdown Support from config file Given we use the config "format_md.yaml" When we run "jrnl -n 1" Then the output should be - """ # 2013 ## June @@ -530,50 +513,43 @@ Feature: Custom formats ### 2013-06-10 15:40 Life is good. But I'm better. - """ Scenario: Text Formatter from config file Given we use the config "format_text.yaml" When we run "jrnl -n 1" Then the output should be - """ [2013-06-10 15:40] Life is good. But I'm better. - """ Scenario Outline: Exporting entries with Cyrillic characters to directory should not fail - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted And we create a cache directory When we run "jrnl 2020-11-21: Первая" When we run "jrnl --format md --file {cache_dir} -on 2020-11-21" Then the cache should contain the files - """ - 2020-11-21_первая.md - """ + 2020-11-21_первая.md Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Export date counts - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl 2020-08-31 01:01: Hi." And we run "jrnl --format dates" Then the output should be - """ - 2020-08-29, 1 - 2020-08-31, 2 - 2020-09-24, 1 - """ + 2020-08-29, 1 + 2020-08-31, 2 + 2020-09-24, 1 Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index dd08502f..e0c60a5e 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -7,10 +7,13 @@ from collections import defaultdict from keyring import backend from keyring import set_keyring from keyring import errors +import random +import string import re import shutil import tempfile from unittest.mock import patch +from xml.etree import ElementTree from pytest_bdd import given from pytest_bdd import then @@ -119,6 +122,11 @@ def password(): return "" +@fixture +def cache_dir(): + return {"exists": False, "path": ""} + + @fixture def str_value(): return "" @@ -212,7 +220,12 @@ def use_password_forever(pw): @when(parse('we run "jrnl" and enter "{user_input}"')) @when('we run "jrnl "') @when('we run "jrnl"') -def we_run(command, config_path, user_input, cli_run, capsys, password, keyring): +def we_run( + command, config_path, user_input, cli_run, capsys, password, keyring, cache_dir +): + if cache_dir["exists"]: + command = command.format(cache_dir=cache_dir["path"]) + args = split_args(command) status = 0 @@ -364,3 +377,111 @@ def password_was_called(cli_run): @then("we should not be prompted for a password") def password_was_not_called(cli_run): assert not cli_run["mocks"]["getpass"].called + + +@then(parse("the cache directory should contain the files\n{file_list}")) +def assert_dir_contains_files(file_list, cache_dir): + actual_files = os.listdir(cache_dir["path"]) + expected_files = file_list.split("\n") + + # sort to deal with inconsistent default file ordering on different OS's + actual_files.sort() + expected_files.sort() + + assert actual_files == expected_files, [actual_files, expected_files] + + +@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} + + +@then(parse('the content of file "{file_path}" in the cache should be\n{file_content}')) +def content_of_file_should_be(file_path, file_content, cache_dir): + assert cache_dir["exists"] + expected_content = file_content.strip().splitlines() + + with open(os.path.join(cache_dir["path"], file_path), "r") as f: + actual_content = f.read().strip().splitlines() + + for actual_line, expected_line in zip(actual_content, expected_content): + if actual_line.startswith("tags: ") and expected_line.startswith("tags: "): + assert_equal_tags_ignoring_order( + actual_line, expected_line, actual_content, expected_content + ) + else: + assert actual_line.strip() == expected_line.strip(), [ + [actual_line.strip(), expected_line.strip()], + [actual_content, expected_content], + ] + + +def assert_equal_tags_ignoring_order( + actual_line, expected_line, actual_content, expected_content +): + actual_tags = set(tag.strip() for tag in actual_line[len("tags: ") :].split(",")) + expected_tags = set( + tag.strip() for tag in expected_line[len("tags: ") :].split(",") + ) + assert actual_tags == expected_tags, [ + [actual_tags, expected_tags], + [expected_content, actual_content], + ] + + +@then(parse("the cache should contain the files\n{file_list}")) +def cache_dir_contains_files(file_list, cache_dir): + assert cache_dir["exists"] + + actual_files = os.listdir(cache_dir["path"]) + expected_files = file_list.split("\n") + + # sort to deal with inconsistent default file ordering on different OS's + actual_files.sort() + expected_files.sort() + + assert actual_files == expected_files, [actual_files, expected_files] + + +@then("the output should be a valid XML string") +def assert_valid_xml_string(cli_run): + output = cli_run["stdout"] + xml_tree = ElementTree.fromstring(output) + assert xml_tree, output + + +@then(parse('"{item}" node in the xml output should have {number:d} elements')) +def assert_xml_output_entries_count(item, number, cli_run): + output = cli_run["stdout"] + xml_tree = ElementTree.fromstring(output) + + xml_tags = (node.tag for node in xml_tree) + assert item in xml_tags, str(list(xml_tags)) + + actual_entry_count = len(xml_tree.find(item)) + assert actual_entry_count == number, actual_entry_count + + +@then(parse('"tags" in the xml output should contain\n{expected_tags}')) +def assert_xml_output_tags(expected_tags, cli_run): + output = cli_run["stdout"] + expected_tags = expected_tags.split("\n") + + xml_tree = ElementTree.fromstring(output) + + xml_tags = (node.tag for node in xml_tree) + assert "tags" in xml_tags, str(list(xml_tags)) + + actual_tags = set(t.attrib["name"] for t in xml_tree.find("tags")) + assert actual_tags == set(expected_tags), [actual_tags, set(expected_tags)] + + +@then(parse('there should be {number:d} "{item}" elements')) +def count_elements(number, item, cli_run): + output = cli_run["stdout"] + xml_tree = ElementTree.fromstring(output) + assert len(xml_tree.findall(".//" + item)) == number diff --git a/tests/step_defs/test_features.py b/tests/step_defs/test_features.py index d04928be..145f8ed6 100644 --- a/tests/step_defs/test_features.py +++ b/tests/step_defs/test_features.py @@ -6,7 +6,7 @@ scenarios("../features/datetime.feature") scenarios("../features/delete.feature") scenarios("../features/encrypt.feature") # scenarios("../features/file_storage.feature") -# scenarios("../features/format.feature") +scenarios("../features/format.feature") # scenarios("../features/import.feature") # scenarios("../features/multiple_journals.feature") scenarios("../features/password.feature") From 3b044e3044e572f50a3f97a043e10f4911d07987 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 10 Apr 2021 12:19:49 -0700 Subject: [PATCH 121/215] Ignore IO errors on Windows Co-authored-by: Jonathan Wren --- pyproject.toml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 37a2f6b3..cb905a23 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,6 +69,12 @@ markers = [ "todo", ] +filterwarnings = [ + "ignore::DeprecationWarning", + "ignore:Flag style will be deprecated in.*", + "ignore:[WinError 32].*", + "ignore:[WinError 5].*" +] [build-system] requires = ["poetry>=1.1"] From ef6ed93ecdc8cbbaedf8937f0a2b0a34c755fe86 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 10 Apr 2021 12:43:51 -0700 Subject: [PATCH 122/215] Add JSON parsing test and combine it with XML parsing test Co-authored-by: Jonathan Wren --- tests/features/format.feature | 8 ++++---- tests/step_defs/conftest.py | 18 +++++++++++------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/tests/features/format.feature b/tests/features/format.feature index 2ac5cdf2..8d3b0765 100644 --- a/tests/features/format.feature +++ b/tests/features/format.feature @@ -5,7 +5,7 @@ Feature: Custom formats And we use the password "test" if prompted When we run "jrnl --format json" Then we should get no error - And the output should be parsable as json + And the output should be valid JSON And "entries" in the json output should have 3 elements And "tags" in the json output should contain "@ipsum" And "tags" in the json output should contain "@tagone" @@ -26,7 +26,7 @@ Feature: Custom formats Given we use the config "dayone.yaml" When we run "jrnl --export json" Then we should get no error - And the output should be parsable as json + And the output should be valid JSON And the json output should contain entries.0.uuid = "4BB1F46946AD439996C9B59DE7C4DDC1" Scenario Outline: Printing a journal that has multiline entries with tags @@ -67,9 +67,9 @@ Feature: Custom formats Given we use the config "" And we use the password "test" if prompted When we run "jrnl -until 'August 2020' --format json" - Then the output should be parsable as json + Then the output should be valid JSON Then we should get no error - And the output should be parsable as json + And the output should be valid JSON And "entries" in the json output should have 2 elements And "tags" in the json output should contain "@ipsum" And "tags" in the json output should contain "@tagone" diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index e0c60a5e..b9eeec20 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -2,6 +2,7 @@ # License: https://www.gnu.org/licenses/gpl-3.0.html import ast +import json import os from collections import defaultdict from keyring import backend @@ -446,13 +447,16 @@ def cache_dir_contains_files(file_list, cache_dir): assert actual_files == expected_files, [actual_files, expected_files] - -@then("the output should be a valid XML string") -def assert_valid_xml_string(cli_run): - output = cli_run["stdout"] - xml_tree = ElementTree.fromstring(output) - assert xml_tree, output - +@then(parse("the output should be valid {language_name}")) +def assert_output_is_valid_language(cli_run, language_name): + language_name = language_name.upper() + if language_name == "XML": + xml_tree = ElementTree.fromstring(cli_run["stdout"]) + assert xml_tree, "Invalid XML" + elif language_name == "JSON": + assert json.loads(cli_run["stdout"]), "Invalid JSON" + else: + assert False, f"Language name {language_name} not recognized" @then(parse('"{item}" node in the xml output should have {number:d} elements')) def assert_xml_output_entries_count(item, number, cli_run): From 3cc3e387c5d90165390e921fddb5970324bef2ae Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 10 Apr 2021 14:26:23 -0700 Subject: [PATCH 123/215] Combine JSON and XML parsing tests Co-authored-by: Jonathan Wren --- tests/features/format.feature | 7 ++-- tests/step_defs/conftest.py | 66 +++++++++++++++++++++++++++-------- 2 files changed, 55 insertions(+), 18 deletions(-) diff --git a/tests/features/format.feature b/tests/features/format.feature index 8d3b0765..a06d4c95 100644 --- a/tests/features/format.feature +++ b/tests/features/format.feature @@ -265,9 +265,10 @@ Feature: Custom formats Given we use the config "tags.yaml" And we use the password "test" if prompted When we run "jrnl --export xml" - Then the output should be a valid XML string - And "entries" node in the xml output should have 2 elements - And "tags" in the xml output should contain + Then the output should be valid XML + Given we parse the output as XML + Then "entries" node in the parsed output should have 2 elements + And "tags" in the parsed output should be @idea @journal @dan diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index b9eeec20..1cc14f5a 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -173,6 +173,11 @@ def which_output_stream(): return None +@fixture +def parsed_output(): + return {"lang": None, "obj": None} + + # ----- STEPS ----- # @given("we have a keyring", target_fixture="keyring") @given(parse("we have a {keyring_type} keyring"), target_fixture="keyring") @@ -447,6 +452,7 @@ def cache_dir_contains_files(file_list, cache_dir): assert actual_files == expected_files, [actual_files, expected_files] + @then(parse("the output should be valid {language_name}")) def assert_output_is_valid_language(cli_run, language_name): language_name = language_name.upper() @@ -458,30 +464,60 @@ def assert_output_is_valid_language(cli_run, language_name): else: assert False, f"Language name {language_name} not recognized" -@then(parse('"{item}" node in the xml output should have {number:d} elements')) -def assert_xml_output_entries_count(item, number, cli_run): + +@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() output = cli_run["stdout"] - xml_tree = ElementTree.fromstring(output) - xml_tags = (node.tag for node in xml_tree) - assert item in xml_tags, str(list(xml_tags)) + if language_name == "XML": + parsed_output = ElementTree.fromstring(output) + elif language_name == "JSON": + parsed_output = json.loads(output) + else: + assert False, f"Language name {language_name} not recognized" - actual_entry_count = len(xml_tree.find(item)) - assert actual_entry_count == number, actual_entry_count + return {"lang": language_name, "obj": parsed_output} -@then(parse('"tags" in the xml output should contain\n{expected_tags}')) -def assert_xml_output_tags(expected_tags, cli_run): - output = cli_run["stdout"] +@then(parse('"{node_name}" node in the parsed output should have {number:d} elements')) +def assert_parsed_output_item_count(node_name, number, parsed_output): + lang = parsed_output["lang"] + obj = parsed_output["obj"] + + if lang == "XML": + xml_node_names = (node.tag for node in obj) + assert node_name in xml_node_names, str(list(xml_node_names)) + + actual_entry_count = len(obj.find(node_name)) + assert actual_entry_count == number, actual_entry_count + + elif lang == "JSON": + assert node_name in obj, [node_name, obj] + assert len(obj[node_name]) == number, len(obj[node_name]) + + else: + assert False, f"Language name {lang} not recognized" + + +@then(parse('"tags" in the parsed output should be\n{expected_tags}')) +def assert_xml_output_tags(expected_tags, cli_run, parsed_output): + lang = parsed_output["lang"] + obj = parsed_output["obj"] expected_tags = expected_tags.split("\n") - xml_tree = ElementTree.fromstring(output) + if lang == "XML": + xml_node_names = (node.tag for node in obj) + assert "tags" in xml_node_names, str(list(xml_node_names)) - xml_tags = (node.tag for node in xml_tree) - assert "tags" in xml_tags, str(list(xml_tags)) + actual_tags = set(t.attrib["name"] for t in obj.find("tags")) + assert actual_tags == set(expected_tags), [actual_tags, set(expected_tags)] - actual_tags = set(t.attrib["name"] for t in xml_tree.find("tags")) - assert actual_tags == set(expected_tags), [actual_tags, set(expected_tags)] + elif lang == "JSON": + assert False, "JSON not implemented in this step" + + else: + assert False, f"Language name {lang} not recognized" @then(parse('there should be {number:d} "{item}" elements')) From 48c9d9fa166ed0a48adf719f5d447bdc5073b1df Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 10 Apr 2021 14:58:10 -0700 Subject: [PATCH 124/215] Implement tag tests in JSON Co-authored-by: Jonathan Wren --- tests/features/format.feature | 12 +++++++----- tests/step_defs/conftest.py | 26 ++++++++++++++++++-------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/tests/features/format.feature b/tests/features/format.feature index a06d4c95..811e0d5e 100644 --- a/tests/features/format.feature +++ b/tests/features/format.feature @@ -6,11 +6,13 @@ Feature: Custom formats When we run "jrnl --format json" Then we should get no error And the output should be valid JSON - And "entries" in the json output should have 3 elements - And "tags" in the json output should contain "@ipsum" - And "tags" in the json output should contain "@tagone" - And "tags" in the json output should contain "@tagthree" - And "tags" in the json output should contain "@tagtwo" + Given we parse the output as JSON + Then "entries" node in the parsed output should have 3 elements + And "tags" in the parsed output should be + @ipsum + @tagone + @tagtwo + @tagthree And entry 1 should have an array "tags" with 3 elements And entry 2 should have an array "tags" with 1 elements And entry 3 should have an array "tags" with 2 elements diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 1cc14f5a..c7732656 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -499,23 +499,33 @@ def assert_parsed_output_item_count(node_name, number, parsed_output): else: assert False, f"Language name {lang} not recognized" - -@then(parse('"tags" in the parsed output should be\n{expected_tags}')) -def assert_xml_output_tags(expected_tags, cli_run, parsed_output): +@then(parse('"{field_name}" in the parsed output should be\n{expected_keys}')) +def assert_xml_output_tags(field_name, expected_keys, cli_run, parsed_output): lang = parsed_output["lang"] obj = parsed_output["obj"] - expected_tags = expected_tags.split("\n") + expected_keys = expected_keys.split("\n") if lang == "XML": xml_node_names = (node.tag for node in obj) - assert "tags" in xml_node_names, str(list(xml_node_names)) + assert field_name in xml_node_names, str(list(xml_node_names)) - actual_tags = set(t.attrib["name"] for t in obj.find("tags")) - assert actual_tags == set(expected_tags), [actual_tags, set(expected_tags)] + if field_name == "tags": + actual_tags = set(t.attrib["name"] for t in obj.find("tags")) + assert set(actual_tags) == set(expected_keys), [actual_tags, set(expected_keys)] + else: + assert False, "This test only works for tags in XML" elif lang == "JSON": - assert False, "JSON not implemented in this step" + my_obj = obj + for node in field_name.split("."): + try: + my_obj = my_obj[int(node)] + except ValueError: + assert field_name in my_obj + my_obj = my_obj[node] + + assert set(expected_keys) == set(my_obj) else: assert False, f"Language name {lang} not recognized" From 430182a0a55f0fd5ac6d8a800a71b46346737569 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 10 Apr 2021 15:26:26 -0700 Subject: [PATCH 125/215] Implement JSON tests and remove "node" nomenclature from tests Co-authored-by: Jonathan Wren --- tests/features/format.feature | 18 ++++++++++-------- tests/step_defs/conftest.py | 29 ++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/tests/features/format.feature b/tests/features/format.feature index 811e0d5e..9c38216f 100644 --- a/tests/features/format.feature +++ b/tests/features/format.feature @@ -7,15 +7,15 @@ Feature: Custom formats Then we should get no error And the output should be valid JSON Given we parse the output as JSON - Then "entries" node in the parsed output should have 3 elements + Then "entries" in the parsed output should have 3 elements And "tags" in the parsed output should be @ipsum @tagone @tagtwo @tagthree - And entry 1 should have an array "tags" with 3 elements - And entry 2 should have an array "tags" with 1 elements - And entry 3 should have an array "tags" with 2 elements + And "entries.0.tags" in the parsed output should have 3 elements + And "entries.1.tags" in the parsed output should have 1 elements + And "entries.2.tags" in the parsed output should have 2 elements Examples: configs | config_file | @@ -24,12 +24,14 @@ Feature: Custom formats | basic_folder.yaml | | basic_dayone.yaml | - Scenario: Exporting dayone to json + Scenario: Exporting dayone to json should include UUID Given we use the config "dayone.yaml" When we run "jrnl --export json" Then we should get no error And the output should be valid JSON - And the json output should contain entries.0.uuid = "4BB1F46946AD439996C9B59DE7C4DDC1" + Given we parse the output as JSON + Then "entries.0.uuid" in the parsed output should be + 4BB1F46946AD439996C9B59DE7C4DDC1 Scenario Outline: Printing a journal that has multiline entries with tags Given we use the config "" @@ -248,7 +250,7 @@ Feature: Custom formats And we use the password "test" if prompted When we run "jrnl --export xml" Then the output should be a valid XML string - And "entries" node in the xml output should have 3 elements + And "entries" in the xml output should have 3 elements And "tags" in the xml output should contain @ipsum @tagone @@ -269,7 +271,7 @@ Feature: Custom formats When we run "jrnl --export xml" Then the output should be valid XML Given we parse the output as XML - Then "entries" node in the parsed output should have 2 elements + Then "entries" in the parsed output should have 2 elements And "tags" in the parsed output should be @idea @journal diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index c7732656..7a651093 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -480,7 +480,7 @@ def parse_output_as_language(cli_run, language_name): return {"lang": language_name, "obj": parsed_output} -@then(parse('"{node_name}" node in the parsed output should have {number:d} elements')) +@then(parse('"{node_name}" in the parsed output should have {number:d} elements')) def assert_parsed_output_item_count(node_name, number, parsed_output): lang = parsed_output["lang"] obj = parsed_output["obj"] @@ -493,14 +493,23 @@ def assert_parsed_output_item_count(node_name, number, parsed_output): assert actual_entry_count == number, actual_entry_count elif lang == "JSON": - assert node_name in obj, [node_name, obj] - assert len(obj[node_name]) == number, len(obj[node_name]) + my_obj = obj + + for node in node_name.split("."): + try: + my_obj = my_obj[int(node)] + except ValueError: + assert node in my_obj + my_obj = my_obj[node] + + assert len(my_obj) == number, len(my_obj) else: assert False, f"Language name {lang} not recognized" + @then(parse('"{field_name}" in the parsed output should be\n{expected_keys}')) -def assert_xml_output_tags(field_name, expected_keys, cli_run, parsed_output): +def assert_output_field_content(field_name, expected_keys, cli_run, parsed_output): lang = parsed_output["lang"] obj = parsed_output["obj"] expected_keys = expected_keys.split("\n") @@ -511,7 +520,10 @@ def assert_xml_output_tags(field_name, expected_keys, cli_run, parsed_output): if field_name == "tags": actual_tags = set(t.attrib["name"] for t in obj.find("tags")) - assert set(actual_tags) == set(expected_keys), [actual_tags, set(expected_keys)] + assert set(actual_tags) == set(expected_keys), [ + actual_tags, + set(expected_keys), + ] else: assert False, "This test only works for tags in XML" @@ -522,10 +534,13 @@ def assert_xml_output_tags(field_name, expected_keys, cli_run, parsed_output): try: my_obj = my_obj[int(node)] except ValueError: - assert field_name in my_obj + assert node in my_obj, [my_obj.keys(), node] my_obj = my_obj[node] - assert set(expected_keys) == set(my_obj) + if type(my_obj) is str: + my_obj = [my_obj] + + assert set(expected_keys) == set(my_obj), [set(my_obj), set(expected_keys)] else: assert False, f"Language name {lang} not recognized" From 11e0e84dcf5f6f56afbb24a99f7654faa5ff8d33 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Mon, 19 Apr 2021 20:06:44 -0700 Subject: [PATCH 126/215] Fix test failing from lack of whitespace Co-authored-by: Jonathan Wren --- tests/features/format.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/features/format.feature b/tests/features/format.feature index 9c38216f..d8454ce0 100644 --- a/tests/features/format.feature +++ b/tests/features/format.feature @@ -47,7 +47,7 @@ Feature: Custom formats | consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In | commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget | venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. - | + | | Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo | ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse | potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget From 849ed16d67f163a14f210348d0808f8519e10842 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Mon, 19 Apr 2021 20:12:14 -0700 Subject: [PATCH 127/215] Install pytest-icdiff and run poetry lock Co-authored-by: Jonathan Wren --- poetry.lock | 41 ++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 1 + 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index e999d3af..34184977 100644 --- a/poetry.lock +++ b/poetry.lock @@ -174,6 +174,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "icdiff" +version = "1.9.1" +description = "improved colored diff" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "importlib-metadata" version = "4.5.0" @@ -382,6 +390,14 @@ importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} [package.extras] dev = ["pre-commit", "tox"] +[[package]] +name = "pprintpp" +version = "0.4.0" +description = "A drop-in replacement for pprint that's actually pretty" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "py" version = "1.10.0" @@ -453,6 +469,19 @@ py = "*" pytest = ">=4.3" six = ">=1.9.0" +[[package]] +name = "pytest-icdiff" +version = "0.5" +description = "use icdiff for better error messages in pytest assertions" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +icdiff = "*" +pprintpp = "*" +pytest = "*" + [[package]] name = "python-dateutil" version = "2.8.1" @@ -629,7 +658,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pyt [metadata] lock-version = "1.1" python-versions = ">=3.7.0, <3.10" -content-hash = "4bb72b50e012bd9b58e47835e1fd5d767ce68ac869505f77bb6ad9d564dbf139" +content-hash = "a0d3f3e30dbe80528547b49ae7bb39c6c1a911e2552d8b10d409daf81cdb28d1" [metadata.files] ansiwrap = [ @@ -730,6 +759,9 @@ ghp-import = [ glob2 = [ {file = "glob2-0.7.tar.gz", hash = "sha256:85c3dbd07c8aa26d63d7aacee34fa86e9a91a3873bc30bf62ec46e531f92ab8c"}, ] +icdiff = [ + {file = "icdiff-1.9.1.tar.gz", hash = "sha256:66972dd03318da55280991db375d3ef6b66d948c67af96c1ebdb21587e86655e"}, +] importlib-metadata = [ {file = "importlib_metadata-4.5.0-py3-none-any.whl", hash = "sha256:833b26fb89d5de469b24a390e9df088d4e52e4ba33b01dc5e0e4f41b81a16c00"}, {file = "importlib_metadata-4.5.0.tar.gz", hash = "sha256:b142cc1dd1342f31ff04bb7d022492b09920cb64fed867cd3ea6f80fe3ebd139"}, @@ -828,6 +860,10 @@ pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, ] +pprintpp = [ + {file = "pprintpp-0.4.0-py2.py3-none-any.whl", hash = "sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d"}, + {file = "pprintpp-0.4.0.tar.gz", hash = "sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403"}, +] py = [ {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, @@ -852,6 +888,9 @@ pytest-bdd = [ {file = "pytest-bdd-4.0.2.tar.gz", hash = "sha256:982489f2f036c7561affe4eeb5b392a37e1ace2a9f260cad747b1c8119e63cfd"}, {file = "pytest_bdd-4.0.2-py2.py3-none-any.whl", hash = "sha256:74ea5a147ea558c99ae83d838e6acbe5c9e6843884a958f8231615d96838733d"}, ] +pytest-icdiff = [ + {file = "pytest-icdiff-0.5.tar.gz", hash = "sha256:3a14097f4385665cb04330e6ae09a3dd430375f717e94482af6944470ad5f100"}, +] python-dateutil = [ {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, diff --git a/pyproject.toml b/pyproject.toml index cb905a23..eac62079 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,6 +51,7 @@ toml = ">=0.10" pyflakes = ">=2.2.0" pytest = ">=6.2" pytest-bdd = "^4.0.1" +pytest-icdiff = "^0.5" yq = ">=2.11" [tool.poetry.scripts] From a6a4417eff33a66c18b5545550b2a30851de5c9e Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Mon, 19 Apr 2021 20:12:43 -0700 Subject: [PATCH 128/215] Fix annoying poetry-generated Windows line endings Co-authored-by: Jonathan Wren --- .gitattributes | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitattributes b/.gitattributes index d47e847c..540af298 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,4 @@ *.journal text eol=lf *.feature text eol=lf +poetry.lock text eol=lf +pyrpoject.toml text eol=lf From 148d3fdb18f8378bf447052268635a5367de7ec0 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Mon, 19 Apr 2021 20:16:37 -0700 Subject: [PATCH 129/215] Update test w/ new steps Co-authored-by: Jonathan Wren --- tests/features/format.feature | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/features/format.feature b/tests/features/format.feature index d8454ce0..330c3a06 100644 --- a/tests/features/format.feature +++ b/tests/features/format.feature @@ -74,12 +74,14 @@ Feature: Custom formats Then the output should be valid JSON Then we should get no error And the output should be valid JSON - And "entries" in the json output should have 2 elements - And "tags" in the json output should contain "@ipsum" - And "tags" in the json output should contain "@tagone" - And "tags" in the json output should contain "@tagtwo" - And entry 1 should have an array "tags" with 3 elements - And entry 2 should have an array "tags" with 1 elements + Given we parse the output as JSON + Then "entries" in the parsed output should have 2 elements + And "tags" in the parsed output should be + @ipsum + @tagone + @tagtwo + And "entries.0.tags" in the parsed output should have 3 elements + And "entries.1.tags" in the parsed output should have 1 elements Examples: configs | config_file | From 36dc01bf306f18a5379f4c508172825a342d7c31 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Mon, 19 Apr 2021 20:50:33 -0700 Subject: [PATCH 130/215] Fixing custom template test and skipping some broken tests Co-authored-by: Jonathan Wren --- tests/features/format.feature | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/features/format.feature b/tests/features/format.feature index 330c3a06..ef126a5b 100644 --- a/tests/features/format.feature +++ b/tests/features/format.feature @@ -92,7 +92,6 @@ Feature: Custom formats Scenario Outline: Exporting using custom templates Given we use the config "" - And we load template "sample.template" And we use the password "test" if prompted When we run "jrnl -1 --format sample" Then the output should be @@ -117,6 +116,7 @@ Feature: Custom formats | basic_folder.yaml | | basic_dayone.yaml | + @skip # .TODO return after editor steps implemented Scenario Outline: Increasing Headings on Markdown export Given we use the config "" And we use the password "test" if prompted @@ -214,6 +214,7 @@ Feature: Custom formats | basic_folder.yaml | # | basic_dayone.yaml | @todo + @skip # .TODO return after editor steps implemented Scenario Outline: Add a blank line to Markdown export if there isn't one already # https://github.com/jrnl-org/jrnl/issues/768 # https://github.com/jrnl-org/jrnl/issues/881 @@ -431,7 +432,7 @@ Feature: Custom formats porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. ... - + Examples: configs | config_file | | basic_onefile.yaml | From ce64d7973bf7a7e09b3d61593fe392f763b6cbca Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Mon, 19 Apr 2021 21:12:37 -0700 Subject: [PATCH 131/215] Implement @skip_win and @skip_editor Co-authored-by: Jonathan Wren --- tests/features/format.feature | 4 ++-- tests/step_defs/conftest.py | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/tests/features/format.feature b/tests/features/format.feature index ef126a5b..648b4dd0 100644 --- a/tests/features/format.feature +++ b/tests/features/format.feature @@ -116,7 +116,7 @@ Feature: Custom formats | basic_folder.yaml | | basic_dayone.yaml | - @skip # .TODO return after editor steps implemented + @skip_editor # .TODO return after editor steps implemented Scenario Outline: Increasing Headings on Markdown export Given we use the config "" And we use the password "test" if prompted @@ -214,7 +214,7 @@ Feature: Custom formats | basic_folder.yaml | # | basic_dayone.yaml | @todo - @skip # .TODO return after editor steps implemented + @skip_editor # .TODO return after editor steps implemented Scenario Outline: Add a blank line to Markdown export if there isn't one already # https://github.com/jrnl-org/jrnl/issues/768 # https://github.com/jrnl-org/jrnl/issues/881 diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 7a651093..7e10883e 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -22,12 +22,14 @@ from pytest_bdd import when from pytest_bdd.parsers import parse from pytest_bdd import parsers from pytest import fixture +from pytest import mark import toml from jrnl import __version__ from jrnl.cli import cli from jrnl.config import load_config from jrnl.os_compat import split_args +from jrnl.os_compat import on_windows class TestKeyring(backend.KeyringBackend): @@ -79,6 +81,22 @@ class FailedKeyring(backend.KeyringBackend): raise errors.KeyringError +# ----- MARKERS ----- # +def pytest_bdd_apply_tag(tag, function): + if tag == "skip_win": + marker = mark.skipif(on_windows, reason="Skip test on Windows") + elif tag == "skip_editor": + marker = mark.skip( + reason="Skipping editor-related test. We should come back to this!" + ) + else: + # Fall back to pytest-bdd's default behavior + return None + + marker(function) + return True + + # ----- UTILS ----- # def failed_msg(msg, expected, actual): return f"{msg}\nExpected:\n{expected}\n---end---\nActual:\n{actual}\n---end---\n" From 3ddfb4d5949eb687605b1b27246a69ba8a7e2ba8 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 24 Apr 2021 14:47:52 -0700 Subject: [PATCH 132/215] Implement editor-related steps in pytest-bdd - Implement mock editor fixture - Add fixture to keep track of editor state - Implement various steps to check editor state Co-authored-by: Micah Jerome Ellison --- jrnl/editor.py | 2 +- poetry.lock | 287 ++++++++++++++++++++++++++++--- pyproject.toml | 9 +- tests/features/write.feature | 175 ++++++++++--------- tests/step_defs/conftest.py | 119 ++++++++++++- tests/step_defs/test_features.py | 16 +- 6 files changed, 475 insertions(+), 133 deletions(-) diff --git a/jrnl/editor.py b/jrnl/editor.py index 086d84db..7c7413e8 100644 --- a/jrnl/editor.py +++ b/jrnl/editor.py @@ -26,7 +26,7 @@ def get_text_from_editor(config, template=""): try: subprocess.call(split_args(config["editor"]) + [tmpfile]) - except Exception as e: + except FileNotFoundError as e: error_msg = f""" {ERROR_COLOR}{str(e)}{RESET_COLOR} diff --git a/poetry.lock b/poetry.lock index 34184977..65670545 100644 --- a/poetry.lock +++ b/poetry.lock @@ -17,6 +17,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "appnope" +version = "0.1.2" +description = "Disable App Nap on macOS >= 10.9" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "argcomplete" version = "1.12.3" @@ -61,6 +69,14 @@ docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"] tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"] +[[package]] +name = "backcall" +version = "0.2.0" +description = "Specifications for callback functions passed in to an API" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "behave" version = "1.2.6" @@ -152,6 +168,14 @@ sdist = ["setuptools-rust (>=0.11.4)"] ssh = ["bcrypt (>=3.1.5)"] test = ["pytest (>=6.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] +[[package]] +name = "decorator" +version = "5.0.9" +description = "Decorators for Humans" +category = "dev" +optional = false +python-versions = ">=3.5" + [[package]] name = "ghp-import" version = "2.0.1" @@ -174,14 +198,6 @@ category = "dev" optional = false python-versions = "*" -[[package]] -name = "icdiff" -version = "1.9.1" -description = "improved colored diff" -category = "dev" -optional = false -python-versions = "*" - [[package]] name = "importlib-metadata" version = "4.5.0" @@ -206,6 +222,74 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "ipdb" +version = "0.13.9" +description = "IPython-enabled pdb" +category = "dev" +optional = false +python-versions = ">=2.7" + +[package.dependencies] +decorator = {version = "*", markers = "python_version > \"3.6\""} +ipython = {version = ">=7.17.0", markers = "python_version > \"3.6\""} +toml = {version = ">=0.10.2", markers = "python_version > \"3.6\""} + +[[package]] +name = "ipython" +version = "7.24.1" +description = "IPython: Productive Interactive Computing" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +appnope = {version = "*", markers = "sys_platform == \"darwin\""} +backcall = "*" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} +pickleshare = "*" +prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" +pygments = "*" +traitlets = ">=4.2" + +[package.extras] +all = ["Sphinx (>=1.3)", "ipykernel", "ipyparallel", "ipywidgets", "nbconvert", "nbformat", "nose (>=0.10.1)", "notebook", "numpy (>=1.17)", "pygments", "qtconsole", "requests", "testpath"] +doc = ["Sphinx (>=1.3)"] +kernel = ["ipykernel"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["notebook", "ipywidgets"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.17)"] + +[[package]] +name = "ipython-genutils" +version = "0.2.0" +description = "Vestigial utilities from IPython" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "jedi" +version = "0.18.0" +description = "An autocompletion tool for Python that can be used for text editors." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +parso = ">=0.8.0,<0.9.0" + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<6.0.0)"] + [[package]] name = "jeepney" version = "0.6.0" @@ -286,6 +370,17 @@ category = "dev" optional = false python-versions = ">=3.6" +[[package]] +name = "matplotlib-inline" +version = "0.1.2" +description = "Inline Matplotlib backend for Jupyter" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +traitlets = "*" + [[package]] name = "mergedeep" version = "1.3.4" @@ -368,6 +463,18 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "parso" +version = "0.8.2" +description = "A Python Parser" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["docopt", "pytest (<6.0.0)"] + [[package]] name = "pathspec" version = "0.8.1" @@ -376,6 +483,25 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "pexpect" +version = "4.8.0" +description = "Pexpect allows easy control of interactive console applications." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "pickleshare" +version = "0.7.5" +description = "Tiny 'shelve'-like database with concurrency support" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "pluggy" version = "0.13.1" @@ -391,9 +517,20 @@ importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} dev = ["pre-commit", "tox"] [[package]] -name = "pprintpp" -version = "0.4.0" -description = "A drop-in replacement for pprint that's actually pretty" +name = "prompt-toolkit" +version = "3.0.19" +description = "Library for building powerful interactive command lines in Python" +category = "dev" +optional = false +python-versions = ">=3.6.1" + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" category = "dev" optional = false python-versions = "*" @@ -422,6 +559,14 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "pygments" +version = "2.9.0" +description = "Pygments is a syntax highlighting package written in Python." +category = "dev" +optional = false +python-versions = ">=3.5" + [[package]] name = "pyparsing" version = "2.4.7" @@ -470,17 +615,16 @@ pytest = ">=4.3" six = ">=1.9.0" [[package]] -name = "pytest-icdiff" -version = "0.5" -description = "use icdiff for better error messages in pytest assertions" +name = "pytest-clarity" +version = "0.3.0a0" +description = "A plugin providing an alternative, colourful diff output for failing assertions." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] -icdiff = "*" -pprintpp = "*" -pytest = "*" +pytest = ">=3.5.0" +termcolor = "1.1.0" [[package]] name = "python-dateutil" @@ -564,6 +708,14 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "termcolor" +version = "1.1.0" +description = "ANSII Color formatting for output in terminal." +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "textwrap3" version = "0.9.2" @@ -580,6 +732,20 @@ category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "traitlets" +version = "5.0.5" +description = "Traitlets Python configuration system" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +ipython-genutils = "*" + +[package.extras] +test = ["pytest"] + [[package]] name = "typed-ast" version = "1.4.3" @@ -618,6 +784,14 @@ python-versions = ">=3.6" [package.extras] watchmedo = ["PyYAML (>=3.10)", "argh (>=0.24.1)"] +[[package]] +name = "wcwidth" +version = "0.2.5" +description = "Measures the displayed width of unicode strings in a terminal" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "xmltodict" version = "0.12.0" @@ -658,7 +832,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pyt [metadata] lock-version = "1.1" python-versions = ">=3.7.0, <3.10" -content-hash = "a0d3f3e30dbe80528547b49ae7bb39c6c1a911e2552d8b10d409daf81cdb28d1" +content-hash = "d9a47064f2050860c955a0871b2bd8899c2f24aaf6482f6a742316fd1fd95ba3" [metadata.files] ansiwrap = [ @@ -669,6 +843,10 @@ appdirs = [ {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, ] +appnope = [ + {file = "appnope-0.1.2-py2.py3-none-any.whl", hash = "sha256:93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442"}, + {file = "appnope-0.1.2.tar.gz", hash = "sha256:dd83cd4b5b460958838f6eb3000c660b1f9caf2a5b1de4264e941512f603258a"}, +] argcomplete = [ {file = "argcomplete-1.12.3-py2.py3-none-any.whl", hash = "sha256:291f0beca7fd49ce285d2f10e4c1c77e9460cf823eef2de54df0c0fec88b0d81"}, {file = "argcomplete-1.12.3.tar.gz", hash = "sha256:2c7dbffd8c045ea534921e63b0be6fe65e88599990d8dc408ac8c542b72a5445"}, @@ -684,6 +862,10 @@ attrs = [ {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, ] +backcall = [ + {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, + {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, +] behave = [ {file = "behave-1.2.6-py2.py3-none-any.whl", hash = "sha256:ebda1a6c9e5bfe95c5f9f0a2794e01c7098b3dde86c10a95d8621c5907ff6f1c"}, {file = "behave-1.2.6.tar.gz", hash = "sha256:b9662327aa53294c1351b0a9c369093ccec1d21026f050c3bd9b3e5cccf81a86"}, @@ -753,15 +935,16 @@ cryptography = [ {file = "cryptography-3.4.7-pp37-pypy37_pp73-manylinux2014_x86_64.whl", hash = "sha256:ee77aa129f481be46f8d92a1a7db57269a2f23052d5f2433b4621bb457081cc9"}, {file = "cryptography-3.4.7.tar.gz", hash = "sha256:3d10de8116d25649631977cb37da6cbdd2d6fa0e0281d014a5b7d337255ca713"}, ] +decorator = [ + {file = "decorator-5.0.9-py3-none-any.whl", hash = "sha256:6e5c199c16f7a9f0e3a61a4a54b3d27e7dad0dbdde92b944426cb20914376323"}, + {file = "decorator-5.0.9.tar.gz", hash = "sha256:72ecfba4320a893c53f9706bebb2d55c270c1e51a28789361aa93e4a21319ed5"}, +] ghp-import = [ {file = "ghp-import-2.0.1.tar.gz", hash = "sha256:753de2eace6e0f7d4edfb3cce5e3c3b98cd52aadb80163303d1d036bda7b4483"}, ] glob2 = [ {file = "glob2-0.7.tar.gz", hash = "sha256:85c3dbd07c8aa26d63d7aacee34fa86e9a91a3873bc30bf62ec46e531f92ab8c"}, ] -icdiff = [ - {file = "icdiff-1.9.1.tar.gz", hash = "sha256:66972dd03318da55280991db375d3ef6b66d948c67af96c1ebdb21587e86655e"}, -] importlib-metadata = [ {file = "importlib_metadata-4.5.0-py3-none-any.whl", hash = "sha256:833b26fb89d5de469b24a390e9df088d4e52e4ba33b01dc5e0e4f41b81a16c00"}, {file = "importlib_metadata-4.5.0.tar.gz", hash = "sha256:b142cc1dd1342f31ff04bb7d022492b09920cb64fed867cd3ea6f80fe3ebd139"}, @@ -770,6 +953,21 @@ iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] +ipdb = [ + {file = "ipdb-0.13.9.tar.gz", hash = "sha256:951bd9a64731c444fd907a5ce268543020086a697f6be08f7cc2c9a752a278c5"}, +] +ipython = [ + {file = "ipython-7.24.1-py3-none-any.whl", hash = "sha256:d513e93327cf8657d6467c81f1f894adc125334ffe0e4ddd1abbb1c78d828703"}, + {file = "ipython-7.24.1.tar.gz", hash = "sha256:9bc24a99f5d19721fb8a2d1408908e9c0520a17fff2233ffe82620847f17f1b6"}, +] +ipython-genutils = [ + {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, + {file = "ipython_genutils-0.2.0.tar.gz", hash = "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"}, +] +jedi = [ + {file = "jedi-0.18.0-py2.py3-none-any.whl", hash = "sha256:18456d83f65f400ab0c2d3319e48520420ef43b23a086fdc05dff34132f0fb93"}, + {file = "jedi-0.18.0.tar.gz", hash = "sha256:92550a404bad8afed881a137ec9a461fed49eca661414be45059329614ed0707"}, +] jeepney = [ {file = "jeepney-0.6.0-py3-none-any.whl", hash = "sha256:aec56c0eb1691a841795111e184e13cad504f7703b9a64f63020816afa79a8ae"}, {file = "jeepney-0.6.0.tar.gz", hash = "sha256:7d59b6622675ca9e993a6bd38de845051d315f8b0c72cca3aef733a20b648657"}, @@ -825,6 +1023,10 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, ] +matplotlib-inline = [ + {file = "matplotlib-inline-0.1.2.tar.gz", hash = "sha256:f41d5ff73c9f5385775d5c0bc13b424535c8402fe70ea8210f93e11f3683993e"}, + {file = "matplotlib_inline-0.1.2-py3-none-any.whl", hash = "sha256:5cf1176f554abb4fa98cb362aa2b55c500147e4bdbb07e3fda359143e1da0811"}, +] mergedeep = [ {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, @@ -852,17 +1054,33 @@ parsedatetime = [ {file = "parsedatetime-2.6-py3-none-any.whl", hash = "sha256:cb96edd7016872f58479e35879294258c71437195760746faffedb692aef000b"}, {file = "parsedatetime-2.6.tar.gz", hash = "sha256:4cb368fbb18a0b7231f4d76119165451c8d2e35951455dfee97c62a87b04d455"}, ] +parso = [ + {file = "parso-0.8.2-py2.py3-none-any.whl", hash = "sha256:a8c4922db71e4fdb90e0d0bc6e50f9b273d3397925e5e60a717e719201778d22"}, + {file = "parso-0.8.2.tar.gz", hash = "sha256:12b83492c6239ce32ff5eed6d3639d6a536170723c6f3f1506869f1ace413398"}, +] pathspec = [ {file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"}, {file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"}, ] +pexpect = [ + {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, + {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, +] +pickleshare = [ + {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, + {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, +] pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, ] -pprintpp = [ - {file = "pprintpp-0.4.0-py2.py3-none-any.whl", hash = "sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d"}, - {file = "pprintpp-0.4.0.tar.gz", hash = "sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403"}, +prompt-toolkit = [ + {file = "prompt_toolkit-3.0.19-py3-none-any.whl", hash = "sha256:7089d8d2938043508aa9420ec18ce0922885304cddae87fb96eebca942299f88"}, + {file = "prompt_toolkit-3.0.19.tar.gz", hash = "sha256:08360ee3a3148bdb5163621709ee322ec34fc4375099afa4bbf751e9b7b7fa4f"}, +] +ptyprocess = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, ] py = [ {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, @@ -876,6 +1094,10 @@ pyflakes = [ {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, ] +pygments = [ + {file = "Pygments-2.9.0-py3-none-any.whl", hash = "sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e"}, + {file = "Pygments-2.9.0.tar.gz", hash = "sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f"}, +] pyparsing = [ {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, @@ -888,8 +1110,8 @@ pytest-bdd = [ {file = "pytest-bdd-4.0.2.tar.gz", hash = "sha256:982489f2f036c7561affe4eeb5b392a37e1ace2a9f260cad747b1c8119e63cfd"}, {file = "pytest_bdd-4.0.2-py2.py3-none-any.whl", hash = "sha256:74ea5a147ea558c99ae83d838e6acbe5c9e6843884a958f8231615d96838733d"}, ] -pytest-icdiff = [ - {file = "pytest-icdiff-0.5.tar.gz", hash = "sha256:3a14097f4385665cb04330e6ae09a3dd430375f717e94482af6944470ad5f100"}, +pytest-clarity = [ + {file = "pytest-clarity-0.3.0a0.tar.gz", hash = "sha256:5cc99e3d9b7969dfe17e5f6072d45a917c59d363b679686d3c958a1ded2e4dcf"}, ] python-dateutil = [ {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, @@ -985,6 +1207,9 @@ six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +termcolor = [ + {file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"}, +] textwrap3 = [ {file = "textwrap3-0.9.2-py2.py3-none-any.whl", hash = "sha256:bf5f4c40faf2a9ff00a9e0791fed5da7415481054cef45bb4a3cfb1f69044ae0"}, {file = "textwrap3-0.9.2.zip", hash = "sha256:5008eeebdb236f6303dcd68f18b856d355f6197511d952ba74bc75e40e0c3414"}, @@ -993,6 +1218,10 @@ toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] +traitlets = [ + {file = "traitlets-5.0.5-py3-none-any.whl", hash = "sha256:69ff3f9d5351f31a7ad80443c2674b7099df13cc41fc5fa6e2f6d3b0330b0426"}, + {file = "traitlets-5.0.5.tar.gz", hash = "sha256:178f4ce988f69189f7e523337a3e11d91c786ded9360174a3d9ca83e79bc5396"}, +] typed-ast = [ {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"}, {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"}, @@ -1053,6 +1282,10 @@ watchdog = [ {file = "watchdog-2.1.2-py3-none-win_ia64.whl", hash = "sha256:104266a778906ae0e971368d368a65c4cd032a490a9fca5ba0b78c6c7ae11720"}, {file = "watchdog-2.1.2.tar.gz", hash = "sha256:0237db4d9024859bea27d0efb59fe75eef290833fd988b8ead7a879b0308c2db"}, ] +wcwidth = [ + {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, + {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, +] xmltodict = [ {file = "xmltodict-0.12.0-py2.py3-none-any.whl", hash = "sha256:8bbcb45cc982f48b2ca8fe7e7827c5d792f217ecf1792626f808bf41c3b86051"}, {file = "xmltodict-0.12.0.tar.gz", hash = "sha256:50d8c638ed7ecb88d90561beedbf720c9b4e851a9fa6c47ebd64e99d166d8a21"}, diff --git a/pyproject.toml b/pyproject.toml index eac62079..2719b954 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,8 +51,9 @@ toml = ">=0.10" pyflakes = ">=2.2.0" pytest = ">=6.2" pytest-bdd = "^4.0.1" -pytest-icdiff = "^0.5" yq = ">=2.11" +ipdb = ">=0.13" +pytest-clarity = "^0.3.0-alpha.0" [tool.poetry.scripts] jrnl = 'jrnl.cli:cli' @@ -66,9 +67,15 @@ force_sort_within_sections = true [tool.pytest.ini_options] minversion = "6.0" +required_plugins = [ + "pytest-bdd" +] markers = [ "todo", ] +addopts = [ + "--pdbcls=IPython.terminal.debugger:Pdb" +] filterwarnings = [ "ignore::DeprecationWarning", diff --git a/tests/features/write.feature b/tests/features/write.feature index eb22e480..aec325d5 100644 --- a/tests/features/write.feature +++ b/tests/features/write.feature @@ -1,49 +1,49 @@ Feature: Writing new entries. Scenario Outline: Multiline entry with punctuation should keep title punctuation - Given we use the config ".yaml" + Given we use the config "" And we use the password "bad doggie no biscuit" if prompted When we run "jrnl This is. the title\\n This is the second line" And we run "jrnl -n 1" Then the output should contain "This is. the title" Examples: configs - | config_file | - | simple | - | empty_folder | - | dayone | - | encrypted | + | config_file | + | simple.yaml | + | empty_folder.yaml | + | dayone.yaml | + | encrypted.yaml | Scenario Outline: Single line entry with period should be split at period - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl This is. the title" And we run "jrnl -1" Then the output should contain "| the title" Examples: configs - | config_file | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: CJK entry should be split at fullwidth period without following space. - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl 七転び。八起き" And we run "jrnl -1" Then the output should contain "| 八起き" Examples: configs - | config_file | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Writing an entry from command line should store the entry - Given we use the config ".yaml" + Given we use the config "" And we use the password "bad doggie no biscuit" if prompted When we run "jrnl 23 july 2013: A cold and stormy day. I ate crisps on the sofa." Then we should see the message "Entry added" @@ -51,49 +51,47 @@ Feature: Writing new entries. Then the output should contain "2013-07-23 09:00 A cold and stormy day." Examples: configs - | config_file | - | simple | - | empty_folder | - | dayone | - | encrypted | + | config_file | + | simple.yaml | + | empty_folder.yaml | + | dayone.yaml | + | encrypted.yaml | Scenario Outline: Writing a partial entry from command line with edit flag should go to the editor - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl this is a partial --edit" Then we should see the message "Entry added" Then the editor should have been called And the editor file content should be - """ - this is a partial - """ - When we run "jrnl -n 1" - Then the output should contain "this is a partial" + this is a partial Examples: configs - | config_file | - | basic_onefile | - | basic_encrypted | - | basic_dayone | - | basic_folder | + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_dayone.yaml | + | basic_folder.yaml | Scenario Outline: Writing an empty entry from the editor should yield "Nothing saved to file" message - Given we use the config ".yaml" + Given we use the config "" + And we write nothing to the editor if opened And we use the password "test" if prompted - When we open the editor and enter nothing + When we run "jrnl --edit" Then the error output should contain "[Nothing saved to file]" + And the editor should have been called Examples: configs - | config_file | - | editor | - | editor_empty_folder | - | dayone | - | basic_encrypted | - | basic_onefile | + | config_file | + | editor.yaml | + | editor_empty_folder.yaml | + | dayone.yaml | + | basic_encrypted.yaml | + | basic_onefile.yaml | @skip Scenario Outline: Writing an empty entry from the command line with no editor should yield nothing - Given we use the config ".yaml" + Given we use the config "" And we use the password "bad doggie no biscuit" if prompted When we run "jrnl" and enter nothing Then the output should be empty @@ -101,15 +99,15 @@ Feature: Writing new entries. And the editor should not have been called Examples: configs - | config_file | - | simple | - | empty_folder | - | encrypted | - # | dayone | @todo + | config_file | + | config_simple.yaml | + | empty_folder.yaml | + | encrypted.yaml | + # | dayone | @todo Scenario Outline: Writing an entry does not print the entire journal # https://github.com/jrnl-org/jrnl/issues/87 - Given we use the config ".yaml" + Given we use the config "" And we use the password "bad doggie no biscuit" if prompted When we run "jrnl 23 july 2013: A cold and stormy day. I ate crisps on the sofa." Then we should see the message "Entry added" @@ -117,33 +115,31 @@ Feature: Writing new entries. Then the output should not contain "Life is good" Examples: configs - | config_file | - | editor | - | editor_empty_folder | - | dayone | - | encrypted | + | config_file | + | editor.yaml | + | editor_empty_folder.yaml | + | dayone.yaml | + | encrypted.yaml | Scenario Outline: Embedded period stays in title - Given we use the config ".yaml" + Given we use the config "" And we use the password "bad doggie no biscuit" if prompted When we run "jrnl 04-24-2014: Created a new website - empty.com. Hope to get a lot of traffic." Then we should see the message "Entry added" When we run "jrnl -1" Then the output should be - """ - 2014-04-24 09:00 Created a new website - empty.com. - | Hope to get a lot of traffic. - """ + 2014-04-24 09:00 Created a new website - empty.com. + | Hope to get a lot of traffic. Examples: configs - | config_file | - | simple | - | empty_folder | - | dayone | - | encrypted | + | config_file | + | simple.yaml | + | empty_folder.yaml | + | dayone.yaml | + | encrypted.yaml | Scenario Outline: Write and read emoji support - Given we use the config ".yaml" + Given we use the config "" And we use the password "bad doggie no biscuit" if prompted When we run "jrnl 23 july 2013: 🌞 sunny day. Saw an 🐘" Then we should see the message "Entry added" @@ -152,14 +148,14 @@ Feature: Writing new entries. And the output should contain "🐘" Examples: configs - | config_file | - | simple | - | empty_folder | - | dayone | - | encrypted | + | config_file | + | simple.yaml | + | empty_folder.yaml | + | dayone.yaml | + | encrypted.yaml | Scenario Outline: Writing an entry at the prompt (no editor) should store the entry - Given we use the config ".yaml" + Given we use the config "" And we use the password "bad doggie no biscuit" if prompted When we run "jrnl" and enter "25 jul 2013: I saw Elvis. He's alive." Then we should get no error @@ -168,10 +164,10 @@ Feature: Writing new entries. And the output should contain "| He's alive." Examples: configs - | config_file | - | simple | - | empty_folder | - | encrypted | + | config_file | + | simple.yaml | + | empty_folder.yaml | + | encrypted.yaml | @todo Scenario: Writing an entry at the prompt (no editor) in DayOne journal @@ -187,26 +183,29 @@ Feature: Writing new entries. Given we use the config "dayone.yaml" When we run "jrnl 01 may 1979: Being born hurts." And we run "jrnl --export json" - Then "entries" in the json output should have 5 elements - And the json output should contain entries.0.creator.software_agent - And the json output should contain entries.0.creator.os_agent - And the json output should contain entries.0.creator.host_name - And the json output should contain entries.0.creator.generation_date - And the json output should contain entries.0.creator.device_agent - And "entries.0.creator.software_agent" in the json output should contain "jrnl" + Then we should get no error + And the output should be valid JSON + Given we parse the output as JSON + Then "entries" in the parsed output should have 5 elements + And "entries.0.creator" in the parsed output should be + software_agent + os_agent + host_name + generation_date + device_agent + And "entries.0.creator.software_agent" in the parsed output should contain + jrnl # fails when system time is UTC (as on Travis-CI) - @skip + # @skip Scenario: Title with an embedded period on DayOne journal Given we use the config "dayone.yaml" When we run "jrnl 04-24-2014: "Ran 6.2 miles today in 1:02:03. I'm feeling sore because I forgot to stretch."" Then we should see the message "Entry added" When we run "jrnl -1" Then the output should be - """ - 2014-04-24 09:00 Ran 6.2 miles today in 1:02:03. - | I'm feeling sore because I forgot to stretch. - """ + 2014-04-24 09:00 Ran 6.2 miles today in 1:02:03. + | I'm feeling sore because I forgot to stretch. Scenario: Opening an folder that's not a DayOne folder should treat as folder journal Given we use the config "empty_folder.yaml" diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 7e10883e..4c1d42d4 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -8,6 +8,7 @@ from collections import defaultdict from keyring import backend from keyring import set_keyring from keyring import errors +from pathlib import Path import random import string import re @@ -191,12 +192,88 @@ def which_output_stream(): return None +@fixture +def editor_input(): + return None + + +@fixture +def num_args(): + return None + + @fixture def parsed_output(): return {"lang": None, "obj": None} +@fixture +def editor_state(): + return { + "command": "", + "intent": {"method": "r", "input": None}, + "tmpfile": {"name": None, "content": None}, + } + + +@fixture +def editor(editor_state): + def _mock_editor(editor_command): + tmpfile = editor_command[-1] + + editor_state["command"] = editor_command + editor_state["tmpfile"]["name"] = tmpfile + + Path(tmpfile).touch() + with open(tmpfile, editor_state["intent"]["method"]) as f: + # Touch the file so jrnl knows it was edited + if editor_state["intent"]["input"] != None: + f.write(editor_state["intent"]["input"]) + + file_content = f.read() + editor_state["tmpfile"]["content"] = file_content + + return _mock_editor + + # ----- STEPS ----- # +@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} + + +@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 + + if isinstance(num_args, int): + assert len(editor_state["command"]) == int(num_args) + + +@then(parse('the editor file content should {comparison} "{str_value}"')) +@then(parse("the editor file content should {comparison} empty")) +@then(parse("the editor file content should {comparison}\n{str_value}")) +def contains_editor_file(comparison, str_value, editor_state): + content = editor_state["tmpfile"]["content"] + # content = f'\n"""\n{content}\n"""\n' + if comparison == "be": + assert content == str_value + elif comparison == "contain": + assert str_value in content + else: + assert False, f"Comparison '{comparison}' not supported" + + @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): @@ -245,7 +322,15 @@ def use_password_forever(pw): @when('we run "jrnl "') @when('we run "jrnl"') def we_run( - command, config_path, user_input, cli_run, capsys, password, keyring, cache_dir + command, + config_path, + user_input, + cli_run, + capsys, + password, + keyring, + cache_dir, + editor, ): if cache_dir["exists"]: command = command.format(cache_dir=cache_dir["path"]) @@ -270,7 +355,8 @@ def we_run( patch("builtins.input", side_effect=user_input) as mock_input, \ patch("getpass.getpass", side_effect=password) as mock_getpass, \ patch("jrnl.install.get_config_path", return_value=config_path), \ - patch("jrnl.config.get_config_path", return_value=config_path) \ + patch("jrnl.config.get_config_path", return_value=config_path), \ + patch("subprocess.call", side_effect=editor) as mock_editor \ : # @TODO: single point of truth for get_config_path (move from all calls from install to config) try: cli(args) @@ -290,6 +376,7 @@ def we_run( "stdin": mock_stdin, "input": mock_input, "getpass": mock_getpass, + "editor": mock_editor, } @@ -526,11 +613,15 @@ def assert_parsed_output_item_count(node_name, number, parsed_output): assert False, f"Language name {lang} not recognized" -@then(parse('"{field_name}" in the parsed output should be\n{expected_keys}')) -def assert_output_field_content(field_name, expected_keys, cli_run, parsed_output): +@then(parse('"{field_name}" in the parsed output should {comparison}\n{expected_keys}')) +def assert_output_field_content( + field_name, comparison, expected_keys, cli_run, parsed_output +): lang = parsed_output["lang"] obj = parsed_output["obj"] expected_keys = expected_keys.split("\n") + if len(expected_keys) == 1: + expected_keys = expected_keys[0] if lang == "XML": xml_node_names = (node.tag for node in obj) @@ -555,10 +646,22 @@ def assert_output_field_content(field_name, expected_keys, cli_run, parsed_outpu assert node in my_obj, [my_obj.keys(), node] my_obj = my_obj[node] - if type(my_obj) is str: - my_obj = [my_obj] - - assert set(expected_keys) == set(my_obj), [set(my_obj), set(expected_keys)] + if comparison == "be": + if type(my_obj) is str: + assert expected_keys == my_obj, [my_obj, expected_keys] + else: + assert set(expected_keys) == set(my_obj), [ + set(my_obj), + set(expected_keys), + ] + elif comparison == "contain": + if type(my_obj) is str: + assert expected_keys in my_obj, [my_obj, expected_keys] + else: + assert all(elem in my_obj for elem in expected_keys), [ + my_obj, + expected_keys, + ] else: assert False, f"Language name {lang} not recognized" diff --git a/tests/step_defs/test_features.py b/tests/step_defs/test_features.py index 145f8ed6..4c8d5ef9 100644 --- a/tests/step_defs/test_features.py +++ b/tests/step_defs/test_features.py @@ -5,13 +5,13 @@ scenarios("../features/core.feature") scenarios("../features/datetime.feature") scenarios("../features/delete.feature") scenarios("../features/encrypt.feature") -# scenarios("../features/file_storage.feature") +scenarios("../features/file_storage.feature") scenarios("../features/format.feature") -# scenarios("../features/import.feature") -# scenarios("../features/multiple_journals.feature") +scenarios("../features/import.feature") +scenarios("../features/multiple_journals.feature") scenarios("../features/password.feature") -# scenarios("../features/search.feature") -# scenarios("../features/star.feature") -# scenarios("../features/tag.feature") -# scenarios("../features/upgrade.feature") -# scenarios("../features/write.feature") +scenarios("../features/search.feature") +scenarios("../features/star.feature") +scenarios("../features/tag.feature") +scenarios("../features/upgrade.feature") +scenarios("../features/write.feature") From d15e6839556bc19774743f749dba5b4ad56f6acf Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 24 Apr 2021 15:06:54 -0700 Subject: [PATCH 133/215] Update search features to use new steps Co-authored-by: Jonathan Wren --- tests/features/search.feature | 247 +++++++++++++++------------------- 1 file changed, 111 insertions(+), 136 deletions(-) diff --git a/tests/features/search.feature b/tests/features/search.feature index 22351b7e..0bd0fb79 100644 --- a/tests/features/search.feature +++ b/tests/features/search.feature @@ -1,7 +1,7 @@ Feature: Searching in a journal Scenario Outline: Displaying entries using -on today should display entries created today - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl today: Adding an entry right now." Then we should see the message "Entry added" When we run "jrnl -on today" @@ -10,13 +10,13 @@ Feature: Searching in a journal And the output should not contain "Life is good" Examples: configs - | config | - | simple | - | empty_folder | - | dayone | + | config_file | + | simple.yaml | + | empty_folder.yaml | + | dayone.yaml | Scenario Outline: Displaying entries using -from day should display correct entries - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl yesterday: This thing happened yesterday" Then we should see the message "Entry added" When we run "jrnl today at 11:59pm: Adding an entry right now." @@ -29,13 +29,13 @@ Feature: Searching in a journal And the output should not contain "This thing happened yesterday" Examples: configs - | config | - | simple | - | empty_folder | - | dayone | + | config_file | + | simple.yaml | + | empty_folder.yaml | + | dayone.yaml | Scenario Outline: Displaying entries using -from and -to day should display correct entries - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl yesterday: This thing happened yesterday" Then we should see the message "Entry added" When we run "jrnl today at 11:59pm: Adding an entry right now." @@ -48,75 +48,72 @@ Feature: Searching in a journal And the output should not contain "A future entry." Examples: configs - | config | - | simple | - | empty_folder | - | dayone | + | config_file | + | simple.yaml | + | empty_folder.yaml | + | dayone.yaml | Scenario Outline: Searching for a string - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl -contains first --short" Then we should get no error And the output should be - """ - 2020-08-29 11:11 Entry the first. - """ + 2020-08-29 11:11 Entry the first. Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Searching for a string within tag results - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl @tagone -contains maybe" Then we should get no error And the output should contain "maybe" Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Searching for a string within AND tag results - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl -and @tagone @tagtwo -contains maybe" Then we should get no error And the output should contain "maybe" Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Searching for a string within NOT tag results - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl -not @tagone -contains lonesome" Then we should get no error And the output should contain "lonesome" Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Searching for dates - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl -on 2020-08-31 --short" Then the output should be "2020-08-31 14:32 A second entry in what I hope to be a long series." - Then we flush the output When we run "jrnl -on 'august 31 2020' --short" Then the output should be "2020-08-31 14:32 A second entry in what I hope to be a long series." Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario: Out of order entries to a Folder journal should be listed in date order Given we use the config "empty_folder.yaml" @@ -126,74 +123,64 @@ Feature: Searching in a journal Then we should see the message "Entry added" When we run "jrnl -2" Then the output should be - """ - 2013-07-23 09:00 Testing folder journal. + 2013-07-23 09:00 Testing folder journal. - 2014-03-07 16:37 Second entry of journal. - """ + 2014-03-07 16:37 Second entry of journal. Scenario Outline: Searching for all tags should show counts of each tag - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl --tags" Then we should get no error And the output should be - """ - @tagtwo : 2 - @tagone : 2 - @tagthree : 1 - @ipsum : 1 - """ + @tagtwo : 2 + @tagone : 2 + @tagthree : 1 + @ipsum : 1 Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Filtering journals should also filter tags - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl -from 'september 2020' --tags" Then we should get no error And the output should be - """ - @tagthree : 1 - @tagone : 1 - """ + @tagthree : 1 + @tagone : 1 Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Excluding a tag should filter out all entries with that tag - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl --tags -not @tagtwo" Then the output should be - """ - @tagthree : 1 - @tagone : 1 - """ + @tagthree : 1 + @tagone : 1 Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Excluding multiple tags should filter out all entries with those tags - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl --tags -not @tagone -not @tagthree" Then the output should be - """ - @tagtwo : 1 - """ + @tagtwo : 1 Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario: DayOne tag searching should work with tags containing a mixture of upper and lower case. # https://github.com/jrnl-org/jrnl/issues/354 @@ -206,113 +193,101 @@ Feature: Searching in a journal When we run "jrnl -2" Then we should get no error And the output should be - """ - 2013-06-09 15:39 My first entry. - | Everything is alright + 2013-06-09 15:39 My first entry. + | Everything is alright - 2013-06-10 15:40 Life is good. - | But I'm better. - """ + 2013-06-10 15:40 Life is good. + | But I'm better. Scenario Outline: Searching by month - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl -month 9 --short" Then the output should be "2020-09-24 09:14 The third entry finally after weeks without writing." - And we flush the output When we run "jrnl -month Sept --short" Then the output should be "2020-09-24 09:14 The third entry finally after weeks without writing." - And we flush the output When we run "jrnl -month September --short" Then the output should be "2020-09-24 09:14 The third entry finally after weeks without writing." Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Searching by day - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl -day 31 --short" Then the output should be "2020-08-31 14:32 A second entry in what I hope to be a long series." Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Searching by year - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl 2019-01-01 01:01: I like this year." And we run "jrnl -year 2019 --short" Then the output should be "2019-01-01 01:01 I like this year." - And we flush the output When we run "jrnl -year 19 --short" Then the output should be "2019-01-01 01:01 I like this year." Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Combining month, day, and year search terms - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl -month 08 -day 29 --short" Then the output should be "2020-08-29 11:11 Entry the first." - And we flush the output When we run "jrnl -day 29 -year 2020 --short" Then the output should be "2020-08-29 11:11 Entry the first." - And we flush the output When we run "jrnl -month 09 -year 2020 --short" Then the output should be "2020-09-24 09:14 The third entry finally after weeks without writing." - And we flush the output When we run "jrnl -month 08 -day 29 -year 2020 --short" Then the output should be "2020-08-29 11:11 Entry the first." Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Searching today in history - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted And we set current date and time to "2020-08-31 14:32" When we run "jrnl 2019-08-31 01:01: Hi, from last year." And we run "jrnl -today-in-history --short" Then the output should be - """ - 2019-08-31 01:01 Hi, from last year. - 2020-08-31 14:32 A second entry in what I hope to be a long series. - """ + 2019-08-31 01:01 Hi, from last year. + 2020-08-31 14:32 A second entry in what I hope to be a long series. Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario: Loading a DayOne Journal Given we use the config "dayone.yaml" When we run "jrnl -from 'feb 2013'" Then we should get no error And the output should be - """ - 2013-05-17 11:39 This entry has tags! + 2013-05-17 11:39 This entry has tags! - 2013-06-17 20:38 This entry has a location. + 2013-06-17 20:38 This entry has a location. - 2013-07-17 11:38 This entry is starred! - """ + 2013-07-17 11:38 This entry is starred! From 8faa3ae32d876163eb3380fb9907ec8564f9f031 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 24 Apr 2021 15:06:10 -0700 Subject: [PATCH 134/215] Update tests to use new steps Co-authored-by: Micah Jerome Ellison --- tests/features/file_storage.feature | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/tests/features/file_storage.feature b/tests/features/file_storage.feature index 33619365..24407fa1 100644 --- a/tests/features/file_storage.feature +++ b/tests/features/file_storage.feature @@ -4,43 +4,38 @@ Feature: Journals iteracting with the file system in a way that users can see Given we use the config "empty_folder.yaml" When we run "jrnl 23 July 2013: Testing folder journal." Then we should see the message "Entry added" - When the journal directory is listed - Then the output should contain "2013/07/23.txt" or "2013\07\23.txt" + And the journal directory should contain + 2013/07/23.txt Scenario: Adding multiple entries to a Folder journal should generate multiple date files Given we use the config "empty_folder.yaml" When we run "jrnl 23 July 2013: Testing folder journal." And we run "jrnl 3/7/2014: Second entry of journal." Then we should see the message "Entry added" - When the journal directory is listed - Then the output should contain "2013/07/23.txt" or "2013\07\23.txt" - Then the output should contain "2014/03/07.txt" or "2014\03\07.txt" + And the journal directory should contain + 2013/07/23.txt Scenario: If the journal and its parent directory don't exist, they should be created Given we use the config "missing_directory.yaml" Then the journal should not exist When we run "jrnl This is a new entry in my journal" Then the journal should exist - When we run "jrnl -n 1" + When we run "jrnl -99 --short" Then the output should contain "This is a new entry in my journal" - And the journal should have 1 entry Scenario: If the journal file doesn't exist, then it should be created Given we use the config "missing_journal.yaml" Then the journal should not exist When we run "jrnl This is a new entry in my journal" Then the journal should exist - When we run "jrnl -n 1" + When we run "jrnl -99 --short" Then the output should contain "This is a new entry in my journal" - And the journal should have 1 entry Scenario: Creating journal with relative path should update to absolute path Given we use the config "missingconfig" When we run "jrnl hello world" and enter - """ - test.txt - n - """ + test.txt + n And we change directory to "features" And we run "jrnl -n 1" Then the output should contain "hello world" @@ -48,6 +43,7 @@ Feature: Journals iteracting with the file system in a way that users can see Scenario: the temporary filename suffix should default to ".jrnl" Given we use the config "editor.yaml" When we run "jrnl --edit" + Then the editor should have been called Then the temporary filename suffix should be ".jrnl" Scenario: the temporary filename suffix should be "-{template_filename}" From 3d29b6b6a1cf6e35278339d0ef8f39667208da5f Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 24 Apr 2021 15:18:11 -0700 Subject: [PATCH 135/215] Fix star and tag feature language and add output should be empty test Co-authored-by: Jonathan Wren --- tests/features/star.feature | 20 ++++++++--------- tests/features/tag.feature | 45 +++++++++++++++++-------------------- tests/step_defs/conftest.py | 15 +++++++------ 3 files changed, 38 insertions(+), 42 deletions(-) diff --git a/tests/features/star.feature b/tests/features/star.feature index f0188056..7b1b42f1 100644 --- a/tests/features/star.feature +++ b/tests/features/star.feature @@ -1,20 +1,20 @@ Feature: Starring entries Scenario Outline: Starring an entry will mark it in the journal file - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl 20 july 2013 *: Best day of my life!" Then we should see the message "Entry added" When we run "jrnl -on 2013-07-20 -starred" Then the output should contain "2013-07-20 09:00 Best day of my life!" Examples: configs - | config_file | - | simple | - | empty_folder | - | dayone | + | config_file | + | simple.yaml | + | empty_folder.yaml | + | dayone.yaml | Scenario Outline: Filtering by starred entries will show only starred entries - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl -starred" Then the output should be empty When we run "jrnl 20 july 2013 *: Best day of my life!" @@ -22,10 +22,10 @@ Feature: Starring entries Then the output should be "2013-07-20 09:00 Best day of my life!" Examples: configs - | config_file | - | simple | - | empty_folder | - | dayone_empty | + | config_file | + | simple.yaml | + | empty_folder.yaml | + | dayone_empty.yaml | Scenario: Starring an entry will mark it in an encrypted journal Given we use the config "encrypted.yaml" diff --git a/tests/features/tag.feature b/tests/features/tag.feature index b7b687b5..a62b5ac8 100644 --- a/tests/features/tag.feature +++ b/tests/features/tag.feature @@ -3,51 +3,46 @@ Feature: Tagging # And format.feature for tag-related output Scenario Outline: Tags should allow certain special characters such as /, +, # - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl 2020-09-26: This is an entry about @os/2 and @c++ and @c#" When we run "jrnl --tags -on 2020-09-26" Then we should get no error And the output should be - """ - @os/2 : 1 - @c++ : 1 - @c# : 1 - """ + @os/2 : 1 + @c++ : 1 + @c# : 1 Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Emails addresses should not be parsed as tags - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl 2020-09-26: The email address test@example.com does not seem to work for me" When we run "jrnl 2020-09-26: The email address test@example.org also does not work for me" When we run "jrnl 2020-09-26: I tried test@example.org and test@example.edu too" - Then we flush the output When we run "jrnl --tags -on 2020-09-26" Then we should get no error And the output should be "[No tags found in journal.]" Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | Scenario Outline: Entry can start and end with tags - Given we use the config ".yaml" + Given we use the config "" When we run "jrnl 2020-09-26: @foo came over, we went to a @bar" When we run "jrnl --tags -on 2020-09-26" Then the output should be - """ - @foo : 1 - @bar : 1 - """ + @foo : 1 + @bar : 1 Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | + | config_file | + | basic_onefile.yaml | + | basic_folder.yaml | + | basic_dayone.yaml | diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 4c1d42d4..ea561ba0 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -419,14 +419,15 @@ def output_should_not_contain(output, cli_run): assert output not in cli_run["stdout"] -@then(parse("the output should be\n{output}")) -@then(parse('the output should be "{output}"')) -@then('the output should be ""') -def output_should_be(output, cli_run): +@then(parse("the output should be\n{str_value}")) +@then(parse('the output should be "{str_value}"')) +@then('the output should be ""') +@then("the output should be empty") +def output_should_be(str_value, cli_run): actual_out = cli_run["stdout"].strip() - output = output.strip() - assert output and output == actual_out, failed_msg( - "Output does not match.", output, actual_out + expected = str_value.strip() + assert expected == actual_out, failed_msg( + "Output does not match.", expected, actual_out ) From e0980cf39624bec5e379df6296146e5655fabd1e Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 24 Apr 2021 15:26:13 -0700 Subject: [PATCH 136/215] Update tests to use more scenario outlines Co-authored-by: Micah Jerome Ellison --- tests/features/import.feature | 100 +++++++++++------------ tests/features/multiple_journals.feature | 66 +++++++++------ 2 files changed, 91 insertions(+), 75 deletions(-) diff --git a/tests/features/import.feature b/tests/features/import.feature index 63b042fc..ef2e62d0 100644 --- a/tests/features/import.feature +++ b/tests/features/import.feature @@ -1,7 +1,7 @@ Feature: Importing data Scenario Outline: --import allows new entry from stdin - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl --import" and pipe "[2020-07-05 15:00] Observe and import." Then we flush the output @@ -9,50 +9,44 @@ Feature: Importing data Then the output should contain "Observe and import" Examples: Configs - | config | - | basic_onefile | - | basic_encrypted | - # | basic_folder | @todo - # | basic_dayone | @todo + | config_file | + | basic_onefile.yaml | + | basic_encrypted.yaml | + # | basic_folder.yaml | @todo + # | basic_dayone.yaml | @todo Scenario Outline: --import allows new large entry from stdin - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl --import" and pipe - """ - [2020-07-05 15:00] Observe and import. - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada quis - est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque augue - et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu consequat. - Aenean ante ex, elementum ut interdum et, mattis eget lacus. In commodo nulla nec - tellus placerat, sed ultricies metus bibendum. Duis eget venenatis erat. In at - dolor dui end of entry. - """ - Then we flush the output + [2020-07-05 15:00] Observe and import. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada quis + est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque augue + et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu consequat. + Aenean ante ex, elementum ut interdum et, mattis eget lacus. In commodo nulla nec + tellus placerat, sed ultricies metus bibendum. Duis eget venenatis erat. In at + dolor dui end of entry. When we run "jrnl -on 2020-07-05" Then the output should contain "2020-07-05 15:00 Observe and import." And the output should contain "Lorem ipsum" And the output should contain "end of entry." Examples: Configs - | config | - | basic_onefile | - | basic_encrypted | - # | basic_folder | @todo - # | basic_dayone | @todo + | config | + | basic_onefile.yaml | + | basic_encrypted.yaml | + # | basic_folder.yaml | @todo + # | basic_dayone.yaml | @todo Scenario Outline: --import allows multiple new entries from stdin - Given we use the config ".yaml" + Given we use the config "" And we use the password "test" if prompted When we run "jrnl --import" and pipe - """ - [2020-07-05 15:00] Observe and import. - Lorem ipsum dolor sit amet, consectetur adipiscing elit. + [2020-07-05 15:00] Observe and import. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. - [2020-07-05 15:01] Twice as nice. - Sed dignissim sed nisl eu consequat. - """ - Then we flush the output + [2020-07-05 15:01] Twice as nice. + Sed dignissim sed nisl eu consequat. When we run "jrnl -on 2020-07-05" Then the output should contain "2020-07-05 15:00 Observe and import." And the output should contain "Lorem ipsum" @@ -60,34 +54,36 @@ Feature: Importing data And the output should contain "Sed dignissim" Examples: Configs - | config | - | basic_onefile | - | basic_encrypted | - # | basic_folder | @todo - # | basic_dayone | @todo + | config | + | basic_onefile.yaml | + | basic_encrypted.yaml | + # | basic_folder.yaml | @todo + # | basic_dayone.yaml | @todo Scenario: --import allows import new entries from file Given we use the config "simple.yaml" - Then the journal should contain "My first entry." - And the journal should contain "Life is good." - But the journal should not contain "I have an @idea" - And the journal should not contain "I met with" + When we run "jrnl -99" + Then the output should contain "My first entry." + And the output should contain "Life is good." + But the output should not contain "I have an @idea" + And the output should not contain "I met with" When we run "jrnl --import --file features/journals/tags.journal" - Then the journal should contain "My first entry." - And the journal should contain "Life is good." - And the journal should contain "PROFIT!" + And we run "jrnl -99" + Then the output should contain "My first entry." + And the output should contain "Life is good." + And the output should contain "PROFIT!" Scenario: --import prioritizes --file over pipe data if both are given Given we use the config "simple.yaml" - Then the journal should contain "My first entry." - And the journal should contain "Life is good." - But the journal should not contain "I have an @idea" - And the journal should not contain "I met with" + When we run "jrnl -99" + Then the output should contain "My first entry." + And the output should contain "Life is good." + But the output should not contain "I have an @idea" + And the output should not contain "I met with" When we run "jrnl --import --file features/journals/tags.journal" and pipe - """ - [2020-07-05 15:00] I should not exist! - """ - Then the journal should contain "My first entry." - And the journal should contain "PROFIT!" - But the journal should not contain "I should not exist!" + [2020-07-05 15:00] I should not exist! + And we run "jrnl -99" + Then the output should contain "My first entry." + And the output should contain "PROFIT!" + But the output should not contain "I should not exist!" diff --git a/tests/features/multiple_journals.feature b/tests/features/multiple_journals.feature index 222be100..4be3ab1c 100644 --- a/tests/features/multiple_journals.feature +++ b/tests/features/multiple_journals.feature @@ -2,20 +2,32 @@ Feature: Multiple journals Scenario: Loading a config with two journals Given we use the config "multiple.yaml" - Then journal "default" should have 2 entries - And journal "work" should have 0 entries + When we run "jrnl -99 --short" + Then the output should be + @todo something + When we run "jrnl work -99 --short" + Then the output should be + @todo something Scenario: Write to default config by default Given we use the config "multiple.yaml" When we run "jrnl this goes to default" - Then journal "default" should have 3 entries - And journal "work" should have 0 entries + When we run "jrnl -99 --short" + Then the output should be + @todo something + When we run "jrnl work -99 --short" + Then the output should be + @todo something Scenario: Write to specified journal Given we use the config "multiple.yaml" When we run "jrnl work a long day in the office" - Then journal "default" should have 2 entries - And journal "work" should have 1 entry + When we run "jrnl -99 --short" + Then the output should be + @todo something + When we run "jrnl work -99 --short" + Then the output should be + @todo something Scenario: Tell user which journal was used Given we use the config "multiple.yaml" @@ -25,41 +37,49 @@ Feature: Multiple journals Scenario: Write to specified journal with a timestamp Given we use the config "multiple.yaml" When we run "jrnl work 23 july 2012: a long day in the office" - Then journal "default" should have 2 entries - And journal "work" should have 1 entry - And journal "work" should contain "2012-07-23" + When we run "jrnl -99 --short" + Then the output should be + @todo something + When we run "jrnl work -99 --short" + Then the output should be + @todo something Scenario: Write to specified journal without a timestamp but with colon Given we use the config "multiple.yaml" When we run "jrnl work : a long day in the office" - Then journal "default" should have 2 entries - And journal "work" should have 1 entry - And journal "work" should contain "a long day in the office" + Then the output should be + @todo something + When we run "jrnl work -99 --short" + Then the output should be + @todo something Scenario: Write to specified journal without a timestamp but with colon Given we use the config "multiple.yaml" When we run "jrnl work: a long day in the office" - Then journal "default" should have 2 entries - And journal "work" should have 1 entry - And journal "work" should contain "a long day in the office" + When we run "jrnl -99 --short" + Then the output should be + @todo something + When we run "jrnl work -99 --short" + Then the output should be + @todo something Scenario: Create new journals as required Given we use the config "multiple.yaml" Then journal "ideas" should not exist When we run "jrnl ideas 23 july 2012: sell my junk on ebay and make lots of money" - Then journal "ideas" should have 1 entry + When we run "jrnl ideas -99 --short" + Then the output should be + @todo something Scenario: Don't crash if no default journal is specified Given we use the config "bug343.yaml" When we run "jrnl a long day in the office" - Then we should see the message "No default journal configured" + Then the output should contain "No default journal configured" Scenario: Don't crash if no file exists for a configured encrypted journal Given we use the config "multiple.yaml" When we run "jrnl new_encrypted Adding first entry" and enter - """ - these three eyes - these three eyes - n - """ - Then we should see the message "Encrypted journal 'new_encrypted' created" + these three eyes + these three eyes + n + Then the output should contain "Encrypted journal 'new_encrypted' created" From e19fab0615fafa26a0262145ed0febaffe3db1c0 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 24 Apr 2021 15:44:19 -0700 Subject: [PATCH 137/215] Add new config file (for use in pytest-bdd) Co-authored-by: Micah Jerome Ellison --- .../configs/editor_markdown_extension.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/data/configs/editor_markdown_extension.yaml diff --git a/tests/data/configs/editor_markdown_extension.yaml b/tests/data/configs/editor_markdown_extension.yaml new file mode 100644 index 00000000..bf3b8d8e --- /dev/null +++ b/tests/data/configs/editor_markdown_extension.yaml @@ -0,0 +1,18 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +editor: "vim" +journals: + default: features/journals/editor_markdown_extension.journal +linewrap: 80 +tagsymbols: "@" +template: features/templates/extension.md +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none From cda07bf8d925653845f930708cc122a0e26b07c8 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 24 Apr 2021 15:44:29 -0700 Subject: [PATCH 138/215] Make steps use new config file Co-authored-by: Micah Jerome Ellison --- tests/features/import.feature | 4 +-- tests/features/upgrade.feature | 62 ++++++++++++---------------------- 2 files changed, 24 insertions(+), 42 deletions(-) diff --git a/tests/features/import.feature b/tests/features/import.feature index ef2e62d0..9de8e216 100644 --- a/tests/features/import.feature +++ b/tests/features/import.feature @@ -32,7 +32,7 @@ Feature: Importing data And the output should contain "end of entry." Examples: Configs - | config | + | config_file | | basic_onefile.yaml | | basic_encrypted.yaml | # | basic_folder.yaml | @todo @@ -54,7 +54,7 @@ Feature: Importing data And the output should contain "Sed dignissim" Examples: Configs - | config | + | config_file | | basic_onefile.yaml | | basic_encrypted.yaml | # | basic_folder.yaml | @todo diff --git a/tests/features/upgrade.feature b/tests/features/upgrade.feature index fda47363..115eb8ff 100644 --- a/tests/features/upgrade.feature +++ b/tests/features/upgrade.feature @@ -3,24 +3,20 @@ Feature: Upgrading Journals from 1.x.x to 2.x.x Scenario: Upgrade and parse journals with square brackets Given we use the config "upgrade_from_195.json" When we run "jrnl -9" and enter "Y" - Then the journal should have 2 entries + When we run "jrnl -99 --short" + Then the output should be + @todo something And the output should contain - """ - 2010-06-10 15:00 A life without chocolate is like a bad analogy. - """ + 2010-06-10 15:00 A life without chocolate is like a bad analogy. And the output should contain - """ - 2013-06-10 15:40 He said "[this] is the best time to be alive". - """ + 2013-06-10 15:40 He said "[this] is the best time to be alive". Scenario: Upgrading a journal encrypted with jrnl 1.x Given we use the config "encrypted_old.json" When we run "jrnl -n 1" and enter - """ - Y - bad doggie no biscuit - bad doggie no biscuit - """ + Y + bad doggie no biscuit + bad doggie no biscuit Then we should be prompted for a password And the output should contain "2013-06-10 15:40 Life is good" @@ -28,44 +24,30 @@ Feature: Upgrading Journals from 1.x.x to 2.x.x Given we use the config "no_colors.yaml" When we run "jrnl -n 1" Then the config should have "colors" set to - """ - { - 'date':'none', - 'title':'none', - 'body':'none', - 'tags':'none' - } - """ + date: none + title: none + body: none + tags: none Scenario: Upgrade and parse journals with little endian date format Given we use the config "upgrade_from_195_little_endian_dates.json" When we run "jrnl -9" and enter "Y" - Then the journal should have 2 entries - And the output should contain - """ - 10.06.2010 15:00 A life without chocolate is like a bad analogy. - """ - And the output should contain - """ - 10.06.2013 15:40 He said "[this] is the best time to be alive". - """ + Then the output should be + 10.06.2010 15:00 A life without chocolate is like a bad analogy. + 10.06.2013 15:40 He said "[this] is the best time to be alive". Scenario: Upgrade with missing journal Given we use the config "upgrade_from_195_with_missing_journal.json" - When we run "jrnl -ls" and enter - """" - Y - """ - Then the output should contain "Error: features/journals/missing.journal does not exist." + When we run "jrnl --list" and enter + Y + Then the error output should contain "Error: features/journals/missing.journal does not exist." And we should get no error Scenario: Upgrade with missing encrypted journal Given we use the config "upgrade_from_195_with_missing_encrypted_journal.json" - When we run "jrnl -ls" and enter - """ - Y - bad doggie no biscuit - """ - Then the output should contain "Error: features/journals/missing.journal does not exist." + When we run "jrnl --list" and enter + Y + bad doggie no biscuit + Then the error output should contain "Error: features/journals/missing.journal does not exist." And the error output should contain "We're all done" And we should get no error From 4aabb73847a4bb7a6e56ef7b324c22b15eac3e80 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 1 May 2021 15:57:16 -0700 Subject: [PATCH 139/215] Implement datetime handling in pytest-bdd - This was awful and convoluted Co-authored-by: Micah Jerome Ellison --- Makefile | 13 +++- jrnl/DayOneJournal.py | 4 +- jrnl/Entry.py | 4 +- jrnl/Journal.py | 10 +-- jrnl/time.py | 22 +++--- tests/features/datetime.feature | 59 +++++++-------- tests/step_defs/conftest.py | 108 ++++++++++++++++++---------- tests/{ => unit}/test_color.py | 0 tests/{ => unit}/test_display.py | 0 tests/{ => unit}/test_exception.py | 0 tests/{ => unit}/test_export.py | 0 tests/{ => unit}/test_install.py | 0 tests/{ => unit}/test_os_compat.py | 0 tests/{ => unit}/test_override.py | 0 tests/{ => unit}/test_parse_args.py | 0 tests/{ => unit}/test_time.py | 0 16 files changed, 133 insertions(+), 87 deletions(-) rename tests/{ => unit}/test_color.py (100%) rename tests/{ => unit}/test_display.py (100%) rename tests/{ => unit}/test_exception.py (100%) rename tests/{ => unit}/test_export.py (100%) rename tests/{ => unit}/test_install.py (100%) rename tests/{ => unit}/test_os_compat.py (100%) rename tests/{ => unit}/test_override.py (100%) rename tests/{ => unit}/test_parse_args.py (100%) rename tests/{ => unit}/test_time.py (100%) diff --git a/Makefile b/Makefile index 8130dade..454702c6 100644 --- a/Makefile +++ b/Makefile @@ -21,9 +21,16 @@ lint: ## Check style with various tools poetry run pyflakes jrnl tests poetry run black --check --diff . -test: lint ## Run unit tests and behave tests - poetry run pytest - poetry run behave --no-skipped --format progress2 +unit: # unit tests + poetry run pytest tests/unit + +e2e: # end-to-end tests + poetry run pytest tests/step_defs --gherkin-terminal-reporter --tb=native --diff-type=unified + +e2e-debug: # end-to-end tests + poetry run pytest tests/step_defs --gherkin-terminal-reporter --tb=native --diff-type=unified -x -vv + +test: lint unit e2e ## Run unit tests and behave tests build: poetry build diff --git a/jrnl/DayOneJournal.py b/jrnl/DayOneJournal.py index 61a60ca0..00271875 100644 --- a/jrnl/DayOneJournal.py +++ b/jrnl/DayOneJournal.py @@ -1,4 +1,4 @@ -from datetime import datetime +import datetime import fnmatch import os from pathlib import Path @@ -116,7 +116,7 @@ class DayOne(Journal.Journal): """Writes only the entries that have been modified into plist files.""" for entry in self.entries: if entry.modified: - utc_time = datetime.utcfromtimestamp( + utc_time = datetime.datetime.utcfromtimestamp( time.mktime(entry.date.timetuple()) ) diff --git a/jrnl/Entry.py b/jrnl/Entry.py index e227794f..56347770 100644 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -2,7 +2,7 @@ # License: https://www.gnu.org/licenses/gpl-3.0.html -from datetime import datetime +import datetime import re import ansiwrap @@ -14,7 +14,7 @@ from .color import highlight_tags_with_background_color class Entry: def __init__(self, journal, date=None, text="", starred=False): self.journal = journal # Reference to journal mainly to access its config - self.date = date or datetime.now() + self.date = date or datetime.datetime.now() self.text = text self._title = None self._body = None diff --git a/jrnl/Journal.py b/jrnl/Journal.py index b889c0d3..181d85c4 100644 --- a/jrnl/Journal.py +++ b/jrnl/Journal.py @@ -2,7 +2,7 @@ # License: https://www.gnu.org/licenses/gpl-3.0.html -from datetime import datetime +import datetime import logging import os import re @@ -134,7 +134,9 @@ class Journal: for match in date_blob_re.finditer(journal_txt): date_blob = match.groups()[0] try: - new_date = datetime.strptime(date_blob, self.config["timeformat"]) + new_date = datetime.datetime.strptime( + date_blob, self.config["timeformat"] + ) except ValueError: # Passing in a date that had brackets around it new_date = time.parse(date_blob, bracketed=True) @@ -347,7 +349,7 @@ class LegacyJournal(Journal): """Parses a journal that's stored in a string and returns a list of entries""" # Entries start with a line that looks like 'date title' - let's figure out how # long the date will be by constructing one - date_length = len(datetime.today().strftime(self.config["timeformat"])) + date_length = len(datetime.datetime.today().strftime(self.config["timeformat"])) # Initialise our current entry entries = [] @@ -357,7 +359,7 @@ class LegacyJournal(Journal): line = line.rstrip() try: # try to parse line as date => new entry begins - new_date = datetime.strptime( + new_date = datetime.datetime.strptime( line[:date_length], self.config["timeformat"] ) diff --git a/jrnl/time.py b/jrnl/time.py index b9ea8e84..f4e7319d 100644 --- a/jrnl/time.py +++ b/jrnl/time.py @@ -1,11 +1,11 @@ # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html -from datetime import datetime +import datetime FAKE_YEAR = 9999 -DEFAULT_FUTURE = datetime(FAKE_YEAR, 12, 31, 23, 59, 59) -DEFAULT_PAST = datetime(FAKE_YEAR, 1, 1, 0, 0) +DEFAULT_FUTURE = datetime.datetime(FAKE_YEAR, 12, 31, 23, 59, 59) +DEFAULT_PAST = datetime.datetime(FAKE_YEAR, 1, 1, 0, 0) def __get_pdt_calendar(): @@ -27,7 +27,7 @@ def parse( """Parses a string containing a fuzzy date and returns a datetime.datetime object""" if not date_str: return None - elif isinstance(date_str, datetime): + elif isinstance(date_str, datetime.datetime): return date_str # Don't try to parse anything with 6 or less characters and was parsed from the existing journal. @@ -44,7 +44,9 @@ def parse( date = dateparse(date_str, default=default_date) if date.year == FAKE_YEAR: - date = datetime(datetime.now().year, date.timetuple()[1:6]) + date = datetime.datetime( + datetime.datetime.now().year, date.timetuple()[1:6] + ) else: year_present = True flag = 1 if date.hour == date.minute == 0 else 2 @@ -52,7 +54,7 @@ def parse( except Exception as e: if e.args[0] == "day is out of range for month": y, m, d, H, M, S = default_date.timetuple()[:6] - default_date = datetime(y, m, d - 1, H, M, S) + default_date = datetime.datetime(y, m, d - 1, H, M, S) else: calendar = __get_pdt_calendar() date, flag = calendar.parse(date_str) @@ -60,26 +62,26 @@ def parse( if not flag: # Oops, unparsable. try: # Try and parse this as a single year year = int(date_str) - return datetime(year, 1, 1) + return datetime.datetime(year, 1, 1) except ValueError: return None except TypeError: return None if flag == 1: # Date found, but no time. Use the default time. - date = datetime( + date = datetime.datetime( *date[:3], hour=23 if inclusive else default_hour or 0, minute=59 if inclusive else default_minute or 0, second=59 if inclusive else 0 ) else: - date = datetime(*date[:6]) + date = datetime.datetime(*date[:6]) # Ugly heuristic: if the date is more than 4 weeks in the future, we got the year wrong. # Rather then this, we would like to see parsedatetime patched so we can tell it to prefer # past dates - dt = datetime.now() - date + dt = datetime.datetime.now() - date if dt.days < -28 and not year_present: date = date.replace(date.year - 1) return date diff --git a/tests/features/datetime.feature b/tests/features/datetime.feature index 0a3f5155..0da3027f 100644 --- a/tests/features/datetime.feature +++ b/tests/features/datetime.feature @@ -36,10 +36,10 @@ Feature: Reading and writing to journal with custom date formats When we run "jrnl " Then we should see the message "Entry added" When we run "jrnl -n 1" - Then the output should contain "" + Then the output should contain "" Examples: Day-first Dates - | config_file | command | output | + | config_file | command | expected_output | | little_endian_dates.yaml | 2020-09-19: My first entry. | 19.09.2020 09:00 My first entry. | | little_endian_dates.yaml | 2020-08-09: My second entry. | 09.08.2020 09:00 My second entry. | | little_endian_dates.yaml | 2020-02-29: Test. | 29.02.2020 09:00 Test. | @@ -53,10 +53,10 @@ Feature: Reading and writing to journal with custom date formats Scenario Outline: Searching for dates with custom date Given we use the config "" When we run "jrnl " - Then the output should be "" + Then the output should be "" Examples: Day-first Dates - | config_file | command | output | + | config_file | command | expected_output | | little_endian_dates.yaml | -on '2013-07-10' --short | 10.07.2013 15:40 Life is good. | | little_endian_dates.yaml | -on 'june 9 2013' --short | 09.06.2013 15:39 My first entry. | | little_endian_dates.yaml | -on 'july 10 2013' --short | 10.07.2013 15:40 Life is good. | @@ -83,47 +83,48 @@ Feature: Reading and writing to journal with custom date formats Then the output should not contain "Life is good" And the output should not contain "But I'm better." - - Scenario Outline: Create entry using day of the week as entry date. + Scenario Outline: Create entry using day of the week as entry date one. Given we use the config "simple.yaml" + And now is "2019-03-12 01:30:32 PM" When we run "jrnl " Then we should see the message "Entry added" When we run "jrnl -1" - Then the output should contain "" + Then the output should contain "" Then the output should contain the date "" Examples: Days of the week - | command | output | date | - | Monday: entry on a monday | entry on a monday | monday at 9am | - | Tuesday: entry on a tuesday | entry on a tuesday | tuesday at 9am | - | Wednesday: entry on a wednesday | entry on a wednesday | wednesday at 9am | - | Thursday: entry on a thursday | entry on a thursday | thursday at 9am | - | Friday: entry on a friday | entry on a friday | friday at 9am | - | Saturday: entry on a saturday | entry on a saturday | saturday at 9am | - | Sunday: entry on a sunday | entry on a sunday | sunday at 9am | - | sunday: entry on a sunday | entry on a sunday | sunday at 9am | - | sUndAy: entry on a sunday | entry on a sunday | sunday at 9am | + | command | expected_output | date | + | Monday: entry on a monday | entry on a monday | 2019-03-11 09:00 | + | Tuesday: entry on a tuesday | entry on a tuesday | 2019-03-05 09:00 | + | Wednesday: entry on a wednesday | entry on a wednesday | 2019-03-06 09:00 | + | Thursday: entry on a thursday | entry on a thursday | 2019-03-07 09:00 | + | Friday: entry on a friday | entry on a friday | 2019-03-08 09:00 | + | Saturday: entry on a saturday | entry on a saturday | 2019-03-09 09:00 | + | Sunday: entry on a sunday | entry on a sunday | 2019-03-10 09:00 | + | sunday: entry on a sunday | entry on a sunday | 2019-03-10 09:00 | + | sUndAy: entry on a sunday | entry on a sunday | 2019-03-10 09:00 | - Scenario Outline: Create entry using day of the week as entry date. + Scenario Outline: Create entry using day of the week as entry date two. Given we use the config "simple.yaml" + And now is "2019-03-12 01:30:32 PM" When we run "jrnl " Then we should see the message "Entry added" When we run "jrnl -1" - Then the output should contain "" + Then the output should contain "" Then the output should contain the date "" Examples: Days of the week - | command | output | date | - | Mon: entry on a monday | entry on a monday | monday at 9am | - | Tue: entry on a tuesday | entry on a tuesday | tuesday at 9am | - | Wed: entry on a wednesday | entry on a wednesday | wednesday at 9am | - | Thu: entry on a thursday | entry on a thursday | thursday at 9am | - | Fri: entry on a friday | entry on a friday | friday at 9am | - | Sat: entry on a saturday | entry on a saturday | saturday at 9am | - | Sun: entry on a sunday | entry on a sunday | sunday at 9am | - | sun: entry on a sunday | entry on a sunday | sunday at 9am | - | sUn: entry on a sunday | entry on a sunday | sunday at 9am | + | command | expected_output | date | + | Mon: entry on a monday | entry on a monday | 2019-03-11 09:00 | + | Tue: entry on a tuesday | entry on a tuesday | 2019-03-05 09:00 | + | Wed: entry on a wednesday | entry on a wednesday | 2019-03-06 09:00 | + | Thu: entry on a thursday | entry on a thursday | 2019-03-07 09:00 | + | Fri: entry on a friday | entry on a friday | 2019-03-08 09:00 | + | Sat: entry on a saturday | entry on a saturday | 2019-03-09 09:00 | + | Sun: entry on a sunday | entry on a sunday | 2019-03-10 09:00 | + | sun: entry on a sunday | entry on a sunday | 2019-03-10 09:00 | + | sUn: entry on a sunday | entry on a sunday | 2019-03-10 09:00 | Scenario: Journals with unreadable dates should still be loaded diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index ea561ba0..e49b8217 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -4,6 +4,7 @@ import ast import json import os +from datetime import datetime from collections import defaultdict from keyring import backend from keyring import set_keyring @@ -15,6 +16,7 @@ import re import shutil import tempfile from unittest.mock import patch +from unittest.mock import MagicMock from xml.etree import ElementTree from pytest_bdd import given @@ -31,6 +33,7 @@ from jrnl.cli import cli from jrnl.config import load_config from jrnl.os_compat import split_args from jrnl.os_compat import on_windows +from jrnl.time import __get_pdt_calendar class TestKeyring(backend.KeyringBackend): @@ -99,10 +102,6 @@ def pytest_bdd_apply_tag(tag, function): # ----- UTILS ----- # -def failed_msg(msg, expected, actual): - return f"{msg}\nExpected:\n{expected}\n---end---\nActual:\n{actual}\n---end---\n" - - def read_value_from_string(string): if string[0] == "{": # Handle value being a dictionary @@ -142,6 +141,11 @@ def password(): return "" +@fixture +def now_date(): + return {"datetime": datetime, "calendar_parse": __get_pdt_calendar()} + + @fixture def cache_dir(): return {"exists": False, "path": ""} @@ -251,6 +255,29 @@ def we_enter_editor(editor_method, editor_input, editor_state): editor_state["intent"] = {"method": file_method, "input": editor_input} +@given(parse('now is ""'), target_fixture="now_date") +@given(parse('now is "{date_str}"'), target_fixture="now_date") +def now_is_str(date_str): + class DatetimeMagicMock(MagicMock): + # needed because jrnl does some reflection on datetime + def __instancecheck__(self, subclass): + return isinstance(subclass, datetime) + + my_date = datetime.strptime(date_str, "%Y-%m-%d %I:%M:%S %p") + + # jrnl uses two different classes to parse dates, so both must be mocked + datetime_mock = DatetimeMagicMock(wraps=datetime) + datetime_mock.now.return_value = my_date + + pdt = __get_pdt_calendar() + calendar_mock = MagicMock(wraps=pdt) + calendar_mock.parse.side_effect = lambda date_str_input: pdt.parse( + date_str_input, my_date + ) + + return {"datetime": datetime_mock, "calendar_parse": calendar_mock} + + @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): @@ -328,9 +355,9 @@ def we_run( cli_run, capsys, password, - keyring, cache_dir, editor, + now_date, ): if cache_dir["exists"]: command = command.format(cache_dir=cache_dir["path"]) @@ -354,6 +381,8 @@ def we_run( patch("sys.stdin.read", side_effect=user_input) as mock_stdin, \ patch("builtins.input", side_effect=user_input) as mock_input, \ patch("getpass.getpass", side_effect=password) as mock_getpass, \ + patch("datetime.datetime", new=now_date["datetime"]), \ + patch("jrnl.time.__get_pdt_calendar", return_value=now_date["calendar_parse"]), \ patch("jrnl.install.get_config_path", return_value=config_path), \ patch("jrnl.config.get_config_path", return_value=config_path), \ patch("subprocess.call", side_effect=editor) as mock_editor \ @@ -392,48 +421,53 @@ def output_should_match(regex, cli_run): assert matches, f"\nRegex didn't match:\n{regex}\n{str(out)}\n{str(matches)}" -@then(parse("the output should contain\n{output}")) -@then(parse('the output should contain "{output}"')) -@then('the output should contain ""') -@then(parse("the {which_output_stream} output should contain\n{output}")) -@then(parse('the {which_output_stream} output should contain "{output}"')) -def output_should_contain(output, which_output_stream, cli_run): - assert output +@then(parse("the output should contain\n{expected_output}")) +@then(parse('the output should contain "{expected_output}"')) +@then('the output should contain ""') +@then(parse("the {which_output_stream} output should contain\n{expected_output}")) +@then(parse('the {which_output_stream} output should contain "{expected_output}"')) +def output_should_contain(expected_output, which_output_stream, cli_run): + assert expected_output if which_output_stream is None: - assert (output in cli_run["stdout"]) or (output in cli_run["stderr"]) + assert (expected_output in cli_run["stdout"]) or ( + expected_output in cli_run["stderr"] + ) elif which_output_stream == "standard": - assert output in cli_run["stdout"] + assert expected_output in cli_run["stdout"] elif which_output_stream == "error": - assert output in cli_run["stderr"] + assert expected_output in cli_run["stderr"] else: - assert output in cli_run[which_output_stream] + assert expected_output in cli_run[which_output_stream] -@then(parse("the output should not contain\n{output}")) -@then(parse('the output should not contain "{output}"')) -@then('the output should not contain ""') -def output_should_not_contain(output, cli_run): - assert output not in cli_run["stdout"] +@then(parse("the output should not contain\n{expected_output}")) +@then(parse('the output should not contain "{expected_output}"')) +@then('the output should not contain ""') +def output_should_not_contain(expected_output, cli_run): + assert expected_output not in cli_run["stdout"] + + +@then(parse("the output should be\n{expected_output}")) +@then(parse('the output should be "{expected_output}"')) +@then('the output should be ""') +def output_should_be(expected_output, cli_run): + actual = cli_run["stdout"].strip() + expected = expected_output.strip() + assert expected == actual -@then(parse("the output should be\n{str_value}")) -@then(parse('the output should be "{str_value}"')) -@then('the output should be ""') @then("the output should be empty") -def output_should_be(str_value, cli_run): - actual_out = cli_run["stdout"].strip() - expected = str_value.strip() - assert expected == actual_out, failed_msg( - "Output does not match.", expected, actual_out - ) +def output_should_be_empty(cli_run): + actual = cli_run["stdout"].strip() + assert actual == "" @then('the output should contain the date ""') -def output_should_contain_date(output, cli_run): - assert output and output in cli_run["stdout"] +def output_should_contain_date(date, cli_run): + assert date and date in cli_run["stdout"] @then("the output should contain pyproject.toml version") @@ -574,12 +608,12 @@ def assert_output_is_valid_language(cli_run, language_name): @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() - output = cli_run["stdout"] + actual_output = cli_run["stdout"] if language_name == "XML": - parsed_output = ElementTree.fromstring(output) + parsed_output = ElementTree.fromstring(actual_output) elif language_name == "JSON": - parsed_output = json.loads(output) + parsed_output = json.loads(actual_output) else: assert False, f"Language name {language_name} not recognized" @@ -669,6 +703,6 @@ def assert_output_field_content( @then(parse('there should be {number:d} "{item}" elements')) def count_elements(number, item, cli_run): - output = cli_run["stdout"] - xml_tree = ElementTree.fromstring(output) + actual_output = cli_run["stdout"] + xml_tree = ElementTree.fromstring(actual_output) assert len(xml_tree.findall(".//" + item)) == number diff --git a/tests/test_color.py b/tests/unit/test_color.py similarity index 100% rename from tests/test_color.py rename to tests/unit/test_color.py diff --git a/tests/test_display.py b/tests/unit/test_display.py similarity index 100% rename from tests/test_display.py rename to tests/unit/test_display.py diff --git a/tests/test_exception.py b/tests/unit/test_exception.py similarity index 100% rename from tests/test_exception.py rename to tests/unit/test_exception.py diff --git a/tests/test_export.py b/tests/unit/test_export.py similarity index 100% rename from tests/test_export.py rename to tests/unit/test_export.py diff --git a/tests/test_install.py b/tests/unit/test_install.py similarity index 100% rename from tests/test_install.py rename to tests/unit/test_install.py diff --git a/tests/test_os_compat.py b/tests/unit/test_os_compat.py similarity index 100% rename from tests/test_os_compat.py rename to tests/unit/test_os_compat.py diff --git a/tests/test_override.py b/tests/unit/test_override.py similarity index 100% rename from tests/test_override.py rename to tests/unit/test_override.py diff --git a/tests/test_parse_args.py b/tests/unit/test_parse_args.py similarity index 100% rename from tests/test_parse_args.py rename to tests/unit/test_parse_args.py diff --git a/tests/test_time.py b/tests/unit/test_time.py similarity index 100% rename from tests/test_time.py rename to tests/unit/test_time.py From ef25c50e16087ec4ea0fff2e16b837385743fcd6 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 15 May 2021 14:50:49 -0700 Subject: [PATCH 140/215] Implement step for directory journals Co-authored-by: Jonathan Wren --- tests/step_defs/conftest.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index e49b8217..3d3b6246 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -31,6 +31,7 @@ import toml from jrnl import __version__ from jrnl.cli import cli from jrnl.config import load_config +from jrnl.config import scope_config from jrnl.os_compat import split_args from jrnl.os_compat import on_windows from jrnl.time import __get_pdt_calendar @@ -112,6 +113,13 @@ def read_value_from_string(string): value = {"bool": lambda v: v.lower() == "true", "int": int, "str": str}[t](value) return value +def assert_directory_contains_files(file_list, directory_path): + assert os.path.isdir(directory_path), "Directory path is not a directory" + + for file in file_list.split("\n"): + fullpath = directory_path + '/' + file + assert os.path.isfile(fullpath) + # ----- FIXTURES ----- # @fixture @@ -358,6 +366,7 @@ def we_run( cache_dir, editor, now_date, + keyring ): if cache_dir["exists"]: command = command.format(cache_dir=cache_dir["path"]) @@ -527,15 +536,17 @@ def password_was_not_called(cli_run): @then(parse("the cache directory should contain the files\n{file_list}")) def assert_dir_contains_files(file_list, cache_dir): - actual_files = os.listdir(cache_dir["path"]) - expected_files = file_list.split("\n") + assert_directory_contains_files(file_list, cache_dir["path"]) - # sort to deal with inconsistent default file ordering on different OS's - actual_files.sort() - expected_files.sort() +@then(parse("the journal directory should contain\n{file_list}")) +def journal_directory_should_contain(config_data, file_list, journal_name): + if not journal_name: + journal_name = "default" - assert actual_files == expected_files, [actual_files, expected_files] + scoped_config = scope_config(config_data, journal_name) + journal_path = scoped_config["journal"] + assert_directory_contains_files(file_list, journal_path) @given("we create a cache directory", target_fixture="cache_dir") def create_cache_dir(temp_dir): @@ -706,3 +717,4 @@ def count_elements(number, item, cli_run): actual_output = cli_run["stdout"] xml_tree = ElementTree.fromstring(actual_output) assert len(xml_tree.findall(".//" + item)) == number + From 7647755e964ac06e93ae5d48e78876be7df59ecd Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 15 May 2021 15:31:23 -0700 Subject: [PATCH 141/215] Implement journal existence check Co-authored-by: Jonathan Wren --- tests/step_defs/conftest.py | 45 ++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 3d3b6246..b64d9965 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -113,12 +113,17 @@ def read_value_from_string(string): value = {"bool": lambda v: v.lower() == "true", "int": int, "str": str}[t](value) return value -def assert_directory_contains_files(file_list, directory_path): - assert os.path.isdir(directory_path), "Directory path is not a directory" + +def does_directory_contain_files(file_list, directory_path): + if not os.path.isdir(directory_path): + return False for file in file_list.split("\n"): - fullpath = directory_path + '/' + file - assert os.path.isfile(fullpath) + fullpath = directory_path + "/" + file + if not os.path.isfile(fullpath): + return False + + return True # ----- FIXTURES ----- # @@ -366,7 +371,7 @@ def we_run( cache_dir, editor, now_date, - keyring + keyring, ): if cache_dir["exists"]: command = command.format(cache_dir=cache_dir["path"]) @@ -536,17 +541,32 @@ def password_was_not_called(cli_run): @then(parse("the cache directory should contain the files\n{file_list}")) def assert_dir_contains_files(file_list, cache_dir): - assert_directory_contains_files(file_list, cache_dir["path"]) + assert does_directory_contain_files(file_list, cache_dir["path"]) + @then(parse("the journal directory should contain\n{file_list}")) -def journal_directory_should_contain(config_data, file_list, journal_name): - if not journal_name: - journal_name = "default" +def journal_directory_should_contain(config_data, file_list): + scoped_config = scope_config(config_data, "default") - scoped_config = scope_config(config_data, journal_name) - journal_path = scoped_config["journal"] + assert does_directory_contain_files(file_list, scoped_config["journal"]) + + +@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") + expected_path = scoped_config["journal"] + + contains_files = does_directory_contain_files(expected_path, ".") + + if should_or_should_not == "should": + assert contains_files + elif should_or_should_not == "should not": + assert not contains_files + else: + raise Exception( + "should_or_should_not valid values are 'should' or 'should not'" + ) - assert_directory_contains_files(file_list, journal_path) @given("we create a cache directory", target_fixture="cache_dir") def create_cache_dir(temp_dir): @@ -717,4 +737,3 @@ def count_elements(number, item, cli_run): actual_output = cli_run["stdout"] xml_tree = ElementTree.fromstring(actual_output) assert len(xml_tree.findall(".//" + item)) == number - From 5d4d68fe327159340a81b2c2fffc95c449a7e8db Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 15 May 2021 16:41:43 -0700 Subject: [PATCH 142/215] Implement directory changing and relative directory test Co-authored-by: Jonathan Wren --- tests/features/file_storage.feature | 4 ++-- tests/step_defs/conftest.py | 14 +++++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/tests/features/file_storage.feature b/tests/features/file_storage.feature index 24407fa1..dc6fd535 100644 --- a/tests/features/file_storage.feature +++ b/tests/features/file_storage.feature @@ -32,11 +32,11 @@ Feature: Journals iteracting with the file system in a way that users can see Then the output should contain "This is a new entry in my journal" Scenario: Creating journal with relative path should update to absolute path - Given we use the config "missingconfig" When we run "jrnl hello world" and enter test.txt n - And we change directory to "features" + Then the output should contain "Journal 'default' created" + When we change directory to "subfolder" And we run "jrnl -n 1" Then the output should contain "hello world" diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index b64d9965..2c58c382 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -141,6 +141,10 @@ def temp_dir(): def working_dir(request): return os.path.join(request.config.rootpath, "tests") +@fixture +def config_path(temp_dir): + os.chdir(temp_dir.name) + return temp_dir.name + "/jrnl.yaml" @fixture def toml_version(working_dir): @@ -197,7 +201,7 @@ def keyring_type(): @fixture def config_data(config_path): return load_config(config_path) - + @fixture def journal_name(): @@ -551,6 +555,14 @@ def journal_directory_should_contain(config_data, file_list): assert does_directory_contain_files(file_list, scoped_config["journal"]) +@when(parse('we change directory to "{directory_name}"')) +def when_we_change_directory(directory_name): + if not os.path.isdir(directory_name): + os.mkdir(directory_name) + + os.chdir(directory_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") From 512fb63e1f9a84ba6322c0e2888ac95e28f2563b Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 15 May 2021 16:51:40 -0700 Subject: [PATCH 143/215] Implement test to check editor temporary filename Co-authored-by: Jonathan Wren --- tests/features/file_storage.feature | 4 ++-- tests/step_defs/conftest.py | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/features/file_storage.feature b/tests/features/file_storage.feature index dc6fd535..f81f2710 100644 --- a/tests/features/file_storage.feature +++ b/tests/features/file_storage.feature @@ -44,9 +44,9 @@ Feature: Journals iteracting with the file system in a way that users can see Given we use the config "editor.yaml" When we run "jrnl --edit" Then the editor should have been called - Then the temporary filename suffix should be ".jrnl" + Then the editor filename should end with ".jrnl" Scenario: the temporary filename suffix should be "-{template_filename}" Given we use the config "editor_markdown_extension.yaml" When we run "jrnl --edit" - Then the temporary filename suffix should be "-extension.md" + Then the editor filename should end with "-extension.md" diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 2c58c382..57a0de03 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -141,11 +141,13 @@ def temp_dir(): def working_dir(request): return os.path.join(request.config.rootpath, "tests") + @fixture def config_path(temp_dir): os.chdir(temp_dir.name) return temp_dir.name + "/jrnl.yaml" + @fixture def toml_version(working_dir): pyproject = os.path.join(working_dir, "..", "pyproject.toml") @@ -201,7 +203,7 @@ def keyring_type(): @fixture def config_data(config_path): return load_config(config_path) - + @fixture def journal_name(): @@ -304,6 +306,13 @@ def count_editor_args(num_args, cli_run, editor_state): assert len(editor_state["command"]) == int(num_args) +@then(parse('the editor filename should end with "{suffix}"')) +def editor_filename_suffix(suffix, editor_state): + editor_filename = editor_state["tmpfile"]["name"] + + assert editor_state["tmpfile"]["name"].endswith(suffix), (editor_filename, suffix) + + @then(parse('the editor file content should {comparison} "{str_value}"')) @then(parse("the editor file content should {comparison} empty")) @then(parse("the editor file content should {comparison}\n{str_value}")) From 44b1762b7d947ab93ec123e48e50b4392ec04ece Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 22 May 2021 12:32:59 -0700 Subject: [PATCH 144/215] Implement stream redirection in pytest-bdd - Take out old steps from format and input tests Co-authored-by: Micah Jerome Ellison --- tests/features/format.feature | 2 -- tests/features/import.feature | 3 +-- tests/step_defs/conftest.py | 17 +++++++++++++---- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/tests/features/format.feature b/tests/features/format.feature index 648b4dd0..b9e2e384 100644 --- a/tests/features/format.feature +++ b/tests/features/format.feature @@ -163,7 +163,6 @@ Feature: Custom formats More stuff more stuff again - Then we flush the output When we run "jrnl -1 --export markdown" Then the output should be # 2020 @@ -224,7 +223,6 @@ Feature: Custom formats [2020-10-29 11:11] First entry. [2020-10-29 11:11] Second entry. [2020-10-29 11:13] Third entry. - Then we flush the output When we run "jrnl -3 --format markdown" Then the output should be # 2020 diff --git a/tests/features/import.feature b/tests/features/import.feature index 9de8e216..d75d6017 100644 --- a/tests/features/import.feature +++ b/tests/features/import.feature @@ -4,8 +4,7 @@ Feature: Importing data Given we use the config "" And we use the password "test" if prompted When we run "jrnl --import" and pipe "[2020-07-05 15:00] Observe and import." - Then we flush the output - When we run "jrnl -c import" + When we run "jrnl -9 --short" Then the output should contain "Observe and import" Examples: Configs diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 57a0de03..9e482737 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -160,6 +160,10 @@ def password(): return "" +@fixture +def input_method(): + return "" + @fixture def now_date(): return {"datetime": datetime, "calendar_parse": __get_pdt_calendar()} @@ -368,10 +372,10 @@ def use_password_forever(pw): return pw -@when(parse('we run "jrnl {command}" and enter\n{user_input}')) -@when(parsers.re('we run "jrnl (?P[^"]+)" and enter "(?P[^"]+)"')) +@when(parse('we run "jrnl {command}" and {input_method}\n{user_input}')) +@when(parsers.re('we run "jrnl (?P[^"]+)" and (?Penter|pipe) "(?P[^"]+)"')) +@when(parse('we run "jrnl" and {input_method} "{user_input}"')) @when(parse('we run "jrnl {command}"')) -@when(parse('we run "jrnl" and enter "{user_input}"')) @when('we run "jrnl "') @when('we run "jrnl"') def we_run( @@ -385,7 +389,11 @@ def we_run( editor, now_date, keyring, + input_method, ): + assert input_method in ['', 'enter', 'pipe'] + is_tty = input_method != 'pipe' + if cache_dir["exists"]: command = command.format(cache_dir=cache_dir["path"]) @@ -393,7 +401,7 @@ def we_run( status = 0 if user_input: - user_input = user_input.splitlines() + user_input = user_input.splitlines() if is_tty else [user_input] if password: password = password.splitlines() @@ -406,6 +414,7 @@ def we_run( with \ patch("sys.argv", ['jrnl'] + args), \ patch("sys.stdin.read", side_effect=user_input) as mock_stdin, \ + patch("sys.stdin.isatty", return_value=is_tty), \ patch("builtins.input", side_effect=user_input) as mock_input, \ patch("getpass.getpass", side_effect=password) as mock_getpass, \ patch("datetime.datetime", new=now_date["datetime"]), \ From b7b7bad2fbc49bd74674140484683dfb1350e42b Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 22 May 2021 14:15:43 -0700 Subject: [PATCH 145/215] Clarify and cleanup tests - Run formatter - Take out old tags - Use new steps on tests Co-authored-by: Micah Jerome Ellison --- tests/data/configs/multiple.yaml | 2 +- tests/features/encrypt.feature | 2 +- tests/features/multiple_journals.feature | 43 +++++++++++++----------- tests/features/search.feature | 2 +- tests/step_defs/conftest.py | 20 +++++++++-- 5 files changed, 44 insertions(+), 25 deletions(-) diff --git a/tests/data/configs/multiple.yaml b/tests/data/configs/multiple.yaml index 65f2c256..1501b383 100644 --- a/tests/data/configs/multiple.yaml +++ b/tests/data/configs/multiple.yaml @@ -6,7 +6,7 @@ highlight: true template: false journals: default: features/journals/simple.journal - ideas: features/journals/nothing.journal + ideas: features/journals/does-not-exist.journal simple: features/journals/simple.journal work: features/journals/work.journal new_encrypted: diff --git a/tests/features/encrypt.feature b/tests/features/encrypt.feature index b9b9ff5a..daa9f109 100644 --- a/tests/features/encrypt.feature +++ b/tests/features/encrypt.feature @@ -3,8 +3,8 @@ Feature: Encrypting and decrypting journals Scenario: Decrypting a journal Given we use the config "encrypted.yaml" When we run "jrnl --decrypt" and enter "bad doggie no biscuit" + Then we should see the message "Journal decrypted" Then the config for journal "default" should have "encrypt" set to "bool:False" - And we should see the message "Journal decrypted" When we run "jrnl -99 --short" Then the output should be 2013-06-09 15:39 My first entry. diff --git a/tests/features/multiple_journals.feature b/tests/features/multiple_journals.feature index 4be3ab1c..cd531ee2 100644 --- a/tests/features/multiple_journals.feature +++ b/tests/features/multiple_journals.feature @@ -4,30 +4,32 @@ Feature: Multiple journals Given we use the config "multiple.yaml" When we run "jrnl -99 --short" Then the output should be - @todo something + 2013-06-09 15:39 My first entry. + 2013-06-10 15:40 Life is good. When we run "jrnl work -99 --short" - Then the output should be - @todo something + Then the output should be empty Scenario: Write to default config by default Given we use the config "multiple.yaml" When we run "jrnl this goes to default" When we run "jrnl -99 --short" - Then the output should be - @todo something + Then the output should contain + 2013-06-09 15:39 My first entry. + 2013-06-10 15:40 Life is good. + Then the output should contain + this goes to default When we run "jrnl work -99 --short" - Then the output should be - @todo something + Then the output should be empty Scenario: Write to specified journal Given we use the config "multiple.yaml" When we run "jrnl work a long day in the office" When we run "jrnl -99 --short" Then the output should be - @todo something + 2013-06-09 15:39 My first entry. + 2013-06-10 15:40 Life is good. When we run "jrnl work -99 --short" - Then the output should be - @todo something + Then the output should contain "a long day in the office" Scenario: Tell user which journal was used Given we use the config "multiple.yaml" @@ -39,29 +41,32 @@ Feature: Multiple journals When we run "jrnl work 23 july 2012: a long day in the office" When we run "jrnl -99 --short" Then the output should be - @todo something + 2013-06-09 15:39 My first entry. + 2013-06-10 15:40 Life is good. When we run "jrnl work -99 --short" Then the output should be - @todo something + 2012-07-23 09:00 a long day in the office Scenario: Write to specified journal without a timestamp but with colon Given we use the config "multiple.yaml" When we run "jrnl work : a long day in the office" Then the output should be - @todo something + 2013-06-09 15:39 My first entry. + 2013-06-10 15:40 Life is good. When we run "jrnl work -99 --short" - Then the output should be - @todo something + Then the output should be contain + a long day in the office Scenario: Write to specified journal without a timestamp but with colon Given we use the config "multiple.yaml" When we run "jrnl work: a long day in the office" When we run "jrnl -99 --short" Then the output should be - @todo something + 2013-06-09 15:39 My first entry. + 2013-06-10 15:40 Life is good. When we run "jrnl work -99 --short" - Then the output should be - @todo something + Then the output should contain + a long day in the office Scenario: Create new journals as required Given we use the config "multiple.yaml" @@ -69,7 +74,7 @@ Feature: Multiple journals When we run "jrnl ideas 23 july 2012: sell my junk on ebay and make lots of money" When we run "jrnl ideas -99 --short" Then the output should be - @todo something + 2012-07-23 09:00 sell my junk on ebay and make lots of money Scenario: Don't crash if no default journal is specified Given we use the config "bug343.yaml" diff --git a/tests/features/search.feature b/tests/features/search.feature index 0bd0fb79..8d951aaf 100644 --- a/tests/features/search.feature +++ b/tests/features/search.feature @@ -267,7 +267,7 @@ Feature: Searching in a journal Scenario Outline: Searching today in history Given we use the config "" And we use the password "test" if prompted - And we set current date and time to "2020-08-31 14:32" + And now is "2020-08-31 02:32:00 PM" When we run "jrnl 2019-08-31 01:01: Hi, from last year." And we run "jrnl -today-in-history --short" Then the output should be diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 9e482737..c6d36f89 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -164,6 +164,7 @@ def password(): def input_method(): return "" + @fixture def now_date(): return {"datetime": datetime, "calendar_parse": __get_pdt_calendar()} @@ -373,7 +374,11 @@ def use_password_forever(pw): @when(parse('we run "jrnl {command}" and {input_method}\n{user_input}')) -@when(parsers.re('we run "jrnl (?P[^"]+)" and (?Penter|pipe) "(?P[^"]+)"')) +@when( + parsers.re( + 'we run "jrnl (?P[^"]+)" and (?Penter|pipe) "(?P[^"]+)"' + ) +) @when(parse('we run "jrnl" and {input_method} "{user_input}"')) @when(parse('we run "jrnl {command}"')) @when('we run "jrnl "') @@ -391,8 +396,8 @@ def we_run( keyring, input_method, ): - assert input_method in ['', 'enter', 'pipe'] - is_tty = input_method != 'pipe' + assert input_method in ["", "enter", "pipe"] + is_tty = input_method != "pipe" if cache_dir["exists"]: command = command.format(cache_dir=cache_dir["path"]) @@ -573,6 +578,15 @@ def journal_directory_should_contain(config_data, file_list): assert does_directory_contain_files(file_list, scoped_config["journal"]) +@then(parse('journal "{journal_name}" should not exist')) +def journal_directory_should_contain(config_data, journal_name): + scoped_config = scope_config(config_data, journal_name) + + assert not does_directory_contain_files( + scoped_config["journal"], "." + ), f'Journal "{journal_name}" does exist' + + @when(parse('we change directory to "{directory_name}"')) def when_we_change_directory(directory_name): if not os.path.isdir(directory_name): From 5572833652bef5473ee53910d57739839be0c223 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 22 May 2021 17:11:14 -0700 Subject: [PATCH 146/215] Rewrite config checking steps in pytest-bdd - Take out old type coersion (it was causing needles complexity) - Take out `read_value_from_string` function - Use taml parser to parse yaml instead of using custom function - Update tests to use new implementation Co-authored-by: Micah Jerome Ellison --- tests/features/encrypt.feature | 6 +-- tests/features/password.feature | 10 ++-- tests/features/upgrade.feature | 14 +++--- tests/step_defs/conftest.py | 81 ++++++++++++++++----------------- 4 files changed, 56 insertions(+), 55 deletions(-) diff --git a/tests/features/encrypt.feature b/tests/features/encrypt.feature index daa9f109..31d53520 100644 --- a/tests/features/encrypt.feature +++ b/tests/features/encrypt.feature @@ -4,7 +4,7 @@ Feature: Encrypting and decrypting journals Given we use the config "encrypted.yaml" When we run "jrnl --decrypt" and enter "bad doggie no biscuit" Then we should see the message "Journal decrypted" - Then the config for journal "default" should have "encrypt" set to "bool:False" + And the config for journal "default" should contain "encrypt: false" When we run "jrnl -99 --short" Then the output should be 2013-06-09 15:39 My first entry. @@ -16,7 +16,7 @@ Feature: Encrypting and decrypting journals # This should warn the user that the journal is already encrypted Given we use the config "simple.yaml" When we run "jrnl --decrypt" - Then the config for journal "default" should have "encrypt" set to "bool:False" + Then the config for journal "default" should contain "encrypt: false" When we run "jrnl -99 --short" Then the output should be 2013-06-09 15:39 My first entry. @@ -35,7 +35,7 @@ Feature: Encrypting and decrypting journals swordfish n Then we should see the message "Journal encrypted" - And the config for journal "default" should have "encrypt" set to "bool:True" + 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" diff --git a/tests/features/password.feature b/tests/features/password.feature index d3116fed..ed8aea5f 100644 --- a/tests/features/password.feature +++ b/tests/features/password.feature @@ -7,7 +7,7 @@ Feature: Using the installed keyring sabertooth sabertooth Y - Then the config for journal "simple" should have "encrypt" set to "bool:True" + Then the config for journal "simple" should contain "encrypt: true" When we run "jrnl simple -n 1" Then the output should contain "2013-06-10 15:40 Life is good" @@ -58,7 +58,7 @@ Feature: Using the installed keyring Then we should see the message "Failed to retrieve keyring" And we should get no error And we should be prompted for a password - And the config for journal "default" should have "encrypt" set to "bool:True" + And the config for journal "default" should contain "encrypt: true" Scenario: Decrypt journal when keyring exists but fails @@ -70,7 +70,7 @@ Feature: Using the installed keyring And we should get no error And we should be prompted for a password And we should see the message "Journal decrypted" - And the config for journal "default" should have "encrypt" set to "bool:False" + And the config for journal "default" should contain "encrypt: false" When we run "jrnl --short" Then we should not be prompted for a password And the output should be @@ -97,7 +97,7 @@ Feature: Using the installed keyring sordfish Then we should be prompted for a password And we should see the message "Passwords did not match" - And the config for journal "default" should not have "encrypt" set + And the config for journal "default" should not contain "encrypt: true" When we run "jrnl --short" Then the output should be 2013-06-09 15:39 My first entry. @@ -115,7 +115,7 @@ Feature: Using the installed keyring Then we should be prompted for a password And we should see the message "Passwords did not match" And we should see the message "Journal encrypted" - And the config for journal "default" should have "encrypt" set to "bool:True" + And the config for journal "default" should contain "encrypt: true" When we run "jrnl -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" diff --git a/tests/features/upgrade.feature b/tests/features/upgrade.feature index 115eb8ff..bb050fa1 100644 --- a/tests/features/upgrade.feature +++ b/tests/features/upgrade.feature @@ -5,7 +5,8 @@ Feature: Upgrading Journals from 1.x.x to 2.x.x When we run "jrnl -9" and enter "Y" When we run "jrnl -99 --short" Then the output should be - @todo something + 2010-06-10 15:00 A life without chocolate is like a bad analogy. + 2013-06-10 15:40 He said "[this] is the best time to be alive".Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada And the output should contain 2010-06-10 15:00 A life without chocolate is like a bad analogy. And the output should contain @@ -23,11 +24,12 @@ Feature: Upgrading Journals from 1.x.x to 2.x.x Scenario: Upgrading a config without colors to colors Given we use the config "no_colors.yaml" When we run "jrnl -n 1" - Then the config should have "colors" set to - date: none - title: none - body: none - tags: none + Then the config should contain + colors: + date: none + title: none + body: none + tags: none Scenario: Upgrade and parse journals with little endian date format Given we use the config "upgrade_from_195_little_endian_dates.json" diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index c6d36f89..4f934d31 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -15,6 +15,7 @@ import string import re import shutil import tempfile +import yaml from unittest.mock import patch from unittest.mock import MagicMock from xml.etree import ElementTree @@ -103,17 +104,6 @@ def pytest_bdd_apply_tag(tag, function): # ----- UTILS ----- # -def read_value_from_string(string): - if string[0] == "{": - # Handle value being a dictionary - return ast.literal_eval(string) - - # Takes strings like "bool:true" or "int:32" and coerces them into proper type - t, value = string.split(":") - value = {"bool": lambda v: v.lower() == "true", "int": int, "str": str}[t](value) - return value - - def does_directory_contain_files(file_list, directory_path): if not os.path.isdir(directory_path): return False @@ -523,37 +513,46 @@ def should_see_the_message(text, cli_run): assert text in out, [text, out] -@then(parse('the config should have "{key}" set to\n{str_value}')) -@then(parse('the config should have "{key}" set to "{str_value}"')) -@then( - parse( - 'the config for journal "{journal_name}" should have "{key}" set to "{str_value}"' - ) -) -@then(parse('the config should {should_not} have "{key}" set')) -@then(parse('the config should {should_not} have "{key}" set')) -@then( - parse( - 'the config for journal "{journal_name}" should {should_not} have "{key}" set' - ) -) -def config_var(config_data, key, str_value, journal_name, should_not): - str_value = read_value_from_string(str_value) if len(str_value) else str_value - - configuration = config_data - if journal_name: - configuration = configuration["journals"][journal_name] - - # is the config a string? - # @todo this should probably be a function - if type(configuration) is str: - configuration = {"journal": configuration} - - if should_not: - assert key not in configuration +def parse_should_or_should_not(should_or_should_not): + if should_or_should_not == "should": + return True + elif should_or_should_not == "should not": + return False else: - assert key in configuration - assert configuration[key] == str_value + raise Exception( + "should_or_should_not valid values are 'should' or 'should not'" + ) + + +@then( + parse( + 'the config for journal "{journal_name}" {should_or_should_not} contain "{some_yaml}"' + ) +) +@then( + parse( + 'the config for journal "{journal_name}" {should_or_should_not} contain\n{some_yaml}' + ) +) +@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): + we_should = parse_should_or_should_not(should_or_should_not) + + actual = config_data + if journal_name: + actual = actual["journals"][journal_name] + + expected = yaml.load(some_yaml, Loader=yaml.FullLoader) + + actual_slice = actual + if type(actual) is dict: + actual_slice = {key: actual.get(key, None) 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") From 0c8efd5331b0f9d73bb7cee7b44ddc18d76846cb Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 22 May 2021 17:25:40 -0700 Subject: [PATCH 147/215] Cleanup last few tests - Misc linting issues - Whitespace cleanup - Entire test suite is now passing - Add misc todo items in comments Co-authored-by: Micah Jerome Ellison --- tests/features/upgrade.feature | 13 ++++++------- tests/step_defs/conftest.py | 8 +++----- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/tests/features/upgrade.feature b/tests/features/upgrade.feature index bb050fa1..e5714a82 100644 --- a/tests/features/upgrade.feature +++ b/tests/features/upgrade.feature @@ -33,16 +33,15 @@ Feature: Upgrading Journals from 1.x.x to 2.x.x Scenario: Upgrade and parse journals with little endian date format Given we use the config "upgrade_from_195_little_endian_dates.json" - When we run "jrnl -9" and enter "Y" - Then the output should be + When we run "jrnl -9 --short" and enter "Y" + Then the output should contain 10.06.2010 15:00 A life without chocolate is like a bad analogy. 10.06.2013 15:40 He said "[this] is the best time to be alive". Scenario: Upgrade with missing journal Given we use the config "upgrade_from_195_with_missing_journal.json" - When we run "jrnl --list" and enter - Y - Then the error output should contain "Error: features/journals/missing.journal does not exist." + When we run "jrnl --list" and enter "Y" + Then the output should contain "Error: features/journals/missing.journal does not exist." And we should get no error Scenario: Upgrade with missing encrypted journal @@ -50,6 +49,6 @@ Feature: Upgrading Journals from 1.x.x to 2.x.x When we run "jrnl --list" and enter Y bad doggie no biscuit - Then the error output should contain "Error: features/journals/missing.journal does not exist." - And the error output should contain "We're all done" + Then the output should contain "Error: features/journals/missing.journal does not exist." + And the output should contain "We're all done" And we should get no error diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 4f934d31..12eb948c 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -1,7 +1,6 @@ # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html -import ast import json import os from datetime import datetime @@ -406,6 +405,7 @@ def we_run( # fmt: off # see: https://github.com/psf/black/issues/664 + # @todo https://docs.python.org/3/library/contextlib.html#contextlib.ExitStack with \ patch("sys.argv", ['jrnl'] + args), \ patch("sys.stdin.read", side_effect=user_input) as mock_stdin, \ @@ -578,7 +578,7 @@ def journal_directory_should_contain(config_data, file_list): @then(parse('journal "{journal_name}" should not exist')) -def journal_directory_should_contain(config_data, journal_name): +def journal_directory_should_not_exist(config_data, journal_name): scoped_config = scope_config(config_data, journal_name) assert not does_directory_contain_files( @@ -723,9 +723,7 @@ def assert_parsed_output_item_count(node_name, number, parsed_output): @then(parse('"{field_name}" in the parsed output should {comparison}\n{expected_keys}')) -def assert_output_field_content( - field_name, comparison, expected_keys, cli_run, parsed_output -): +def assert_output_field_content(field_name, comparison, expected_keys, parsed_output): lang = parsed_output["lang"] obj = parsed_output["obj"] expected_keys = expected_keys.split("\n") From fd349fb0fcdfd356a02065bcc733172b10f9d32c Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 5 Jun 2021 15:54:28 -0700 Subject: [PATCH 148/215] Implement ExitStack to handle mocks in pytest-bdd - Fix failing DayOne test - Make format and clean up extraneous comment Co-authored-by: Jonathan Wren --- tests/features/write.feature | 6 +-- tests/step_defs/conftest.py | 83 +++++++++++++++++++++++------------- 2 files changed, 56 insertions(+), 33 deletions(-) diff --git a/tests/features/write.feature b/tests/features/write.feature index aec325d5..1cb822b5 100644 --- a/tests/features/write.feature +++ b/tests/features/write.feature @@ -196,16 +196,14 @@ Feature: Writing new entries. And "entries.0.creator.software_agent" in the parsed output should contain jrnl - # fails when system time is UTC (as on Travis-CI) - # @skip Scenario: Title with an embedded period on DayOne journal Given we use the config "dayone.yaml" - When we run "jrnl 04-24-2014: "Ran 6.2 miles today in 1:02:03. I'm feeling sore because I forgot to stretch."" + When we run "jrnl 04-24-2014: Ran 6.2 miles today in 1:02:03. I am feeling sore because I forgot to stretch." Then we should see the message "Entry added" When we run "jrnl -1" Then the output should be 2014-04-24 09:00 Ran 6.2 miles today in 1:02:03. - | I'm feeling sore because I forgot to stretch. + | I am feeling sore because I forgot to stretch. Scenario: Opening an folder that's not a DayOne folder should treat as folder journal Given we use the config "empty_folder.yaml" diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 12eb948c..45fd73eb 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -5,6 +5,7 @@ import json import os from datetime import datetime from collections import defaultdict +from contextlib import ExitStack from keyring import backend from keyring import set_keyring from keyring import errors @@ -121,6 +122,11 @@ def cli_run(): return {"status": 0, "stdout": None, "stderr": None} +@fixture +def mocks(): + return dict() + + @fixture def temp_dir(): return tempfile.TemporaryDirectory() @@ -154,11 +160,6 @@ def input_method(): return "" -@fixture -def now_date(): - return {"datetime": datetime, "calendar_parse": __get_pdt_calendar()} - - @fixture def cache_dir(): return {"exists": False, "path": ""} @@ -268,27 +269,37 @@ def we_enter_editor(editor_method, editor_input, editor_state): editor_state["intent"] = {"method": file_method, "input": editor_input} -@given(parse('now is ""'), target_fixture="now_date") -@given(parse('now is "{date_str}"'), target_fixture="now_date") -def now_is_str(date_str): +@given(parse('now is ""')) +@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) - my_date = datetime.strptime(date_str, "%Y-%m-%d %I:%M:%S %p") + 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.return_value = my_date + 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, my_date + date_str_input, mocked_now() ) - return {"datetime": datetime_mock, "calendar_parse": calendar_mock} + mocks["datetime"] = patch("datetime.datetime", new=datetime_mock) + mocks["calendar_parse"] = patch( + "jrnl.time.__get_pdt_calendar", return_value=calendar_mock + ) @then(parse("the editor should have been called")) @@ -381,9 +392,9 @@ def we_run( password, cache_dir, editor, - now_date, keyring, input_method, + mocks, ): assert input_method in ["", "enter", "pipe"] is_tty = input_method != "pipe" @@ -403,21 +414,36 @@ def we_run( if not password and user_input: password = user_input - # fmt: off - # see: https://github.com/psf/black/issues/664 - # @todo https://docs.python.org/3/library/contextlib.html#contextlib.ExitStack - with \ - patch("sys.argv", ['jrnl'] + args), \ - patch("sys.stdin.read", side_effect=user_input) as mock_stdin, \ - patch("sys.stdin.isatty", return_value=is_tty), \ - patch("builtins.input", side_effect=user_input) as mock_input, \ - patch("getpass.getpass", side_effect=password) as mock_getpass, \ - patch("datetime.datetime", new=now_date["datetime"]), \ - patch("jrnl.time.__get_pdt_calendar", return_value=now_date["calendar_parse"]), \ - patch("jrnl.install.get_config_path", return_value=config_path), \ - patch("jrnl.config.get_config_path", return_value=config_path), \ - patch("subprocess.call", side_effect=editor) as mock_editor \ - : # @TODO: single point of truth for get_config_path (move from all calls from install to config) + with ExitStack() as stack: + + stack.enter_context(patch("sys.argv", ["jrnl"] + args)) + + mock_stdin = stack.enter_context( + patch("sys.stdin.read", side_effect=user_input) + ) + stack.enter_context(patch("sys.stdin.isatty", return_value=is_tty)) + mock_input = stack.enter_context( + patch("builtins.input", side_effect=user_input) + ) + mock_getpass = stack.enter_context( + patch("getpass.getpass", side_effect=password) + ) + + if "datetime" in mocks: + stack.enter_context(mocks["datetime"]) + stack.enter_context(mocks["calendar_parse"]) + + # stack.enter_context(patch("datetime.datetime", new=mocks["datetime"])) + # stack.enter_context(patch("jrnl.time.__get_pdt_calendar", return_value=mocks["calendar_parse"])) + + stack.enter_context( + patch("jrnl.install.get_config_path", return_value=config_path) + ) + stack.enter_context( + patch("jrnl.config.get_config_path", return_value=config_path) + ) + mock_editor = stack.enter_context(patch("subprocess.call", side_effect=editor)) + try: cli(args) except StopIteration: @@ -425,7 +451,6 @@ def we_run( pass except SystemExit as e: status = e.code - # fmt: on captured = capsys.readouterr() From 54e5e96ad28de4555659352ca8742194269feb4b Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 5 Jun 2021 16:35:09 -0700 Subject: [PATCH 149/215] Force GitHub Actions to preserve line endings Co-authored-by: Jonathan Wren --- .github/workflows/testing.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index a90b939a..47710ca2 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -29,6 +29,7 @@ jobs: os: [ ubuntu-latest, macos-latest, windows-latest ] steps: + - run: git config --global core.autocrlf false - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} From c5a7d7027ced56c2175326ad7b7d8d5ab4086302 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 19 Jun 2021 16:39:30 -0700 Subject: [PATCH 150/215] Move pytest-bdd code into separate files Now that all the tests are passing, this breaks them up into a few different files to make everything more organized. Note: Pyflakes is complaining about some unused import statements. --- tests/step_defs/conftest.py | 794 +-------------------------------- tests/step_defs/fixtures.py | 202 +++++++++ tests/step_defs/given_steps.py | 133 ++++++ tests/step_defs/helpers.py | 41 ++ tests/step_defs/then_steps.py | 331 ++++++++++++++ tests/step_defs/when_steps.py | 113 +++++ 6 files changed, 827 insertions(+), 787 deletions(-) create mode 100644 tests/step_defs/fixtures.py create mode 100644 tests/step_defs/given_steps.py create mode 100644 tests/step_defs/helpers.py create mode 100644 tests/step_defs/then_steps.py create mode 100644 tests/step_defs/when_steps.py diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index 45fd73eb..d73fcec4 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -1,96 +1,18 @@ # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html -import json -import os -from datetime import datetime -from collections import defaultdict -from contextlib import ExitStack -from keyring import backend -from keyring import set_keyring -from keyring import errors -from pathlib import Path -import random -import string -import re -import shutil -import tempfile -import yaml -from unittest.mock import patch -from unittest.mock import MagicMock -from xml.etree import ElementTree - -from pytest_bdd import given -from pytest_bdd import then -from pytest_bdd import when -from pytest_bdd.parsers import parse -from pytest_bdd import parsers -from pytest import fixture -from pytest import mark -import toml - -from jrnl import __version__ -from jrnl.cli import cli -from jrnl.config import load_config -from jrnl.config import scope_config -from jrnl.os_compat import split_args from jrnl.os_compat import on_windows -from jrnl.time import __get_pdt_calendar +from pytest import mark + +from .fixtures import * +from .given_steps import * +from .when_steps import * +from .then_steps import * -class TestKeyring(backend.KeyringBackend): - """A test keyring that just stores its values in a hash""" - - priority = 1 - keys = defaultdict(dict) - - def set_password(self, servicename, username, password): - self.keys[servicename][username] = password - - def get_password(self, servicename, username): - return self.keys[servicename].get(username) - - def delete_password(self, servicename, username): - self.keys[servicename][username] = None - - -class NoKeyring(backend.KeyringBackend): - """A keyring that simulated an environment with no keyring backend.""" - - priority = 2 - keys = defaultdict(dict) - - def set_password(self, servicename, username, password): - raise errors.NoKeyringError - - def get_password(self, servicename, username): - raise errors.NoKeyringError - - def delete_password(self, servicename, username): - raise errors.NoKeyringError - - -class FailedKeyring(backend.KeyringBackend): - """ - A keyring that cannot be retrieved. - """ - - priority = 2 - - def set_password(self, servicename, username, password): - raise errors.KeyringError - - def get_password(self, servicename, username): - raise errors.KeyringError - - def delete_password(self, servicename, username): - raise errors.KeyringError - - -# ----- MARKERS ----- # def pytest_bdd_apply_tag(tag, function): if tag == "skip_win": - marker = mark.skipif(on_windows, reason="Skip test on Windows") + marker = mark.skipif(on_windows(), reason="Skip test on Windows") elif tag == "skip_editor": marker = mark.skip( reason="Skipping editor-related test. We should come back to this!" @@ -101,705 +23,3 @@ def pytest_bdd_apply_tag(tag, function): marker(function) return True - - -# ----- UTILS ----- # -def does_directory_contain_files(file_list, directory_path): - if not os.path.isdir(directory_path): - return False - - for file in file_list.split("\n"): - fullpath = directory_path + "/" + file - if not os.path.isfile(fullpath): - return False - - return True - - -# ----- FIXTURES ----- # -@fixture -def cli_run(): - return {"status": 0, "stdout": None, "stderr": None} - - -@fixture -def mocks(): - return dict() - - -@fixture -def temp_dir(): - return tempfile.TemporaryDirectory() - - -@fixture -def working_dir(request): - return os.path.join(request.config.rootpath, "tests") - - -@fixture -def config_path(temp_dir): - os.chdir(temp_dir.name) - return temp_dir.name + "/jrnl.yaml" - - -@fixture -def toml_version(working_dir): - pyproject = os.path.join(working_dir, "..", "pyproject.toml") - pyproject_contents = toml.load(pyproject) - return pyproject_contents["tool"]["poetry"]["version"] - - -@fixture -def password(): - return "" - - -@fixture -def input_method(): - return "" - - -@fixture -def cache_dir(): - return {"exists": False, "path": ""} - - -@fixture -def str_value(): - return "" - - -@fixture -def command(): - return "" - - -@fixture -def should_not(): - return False - - -@fixture -def user_input(): - return "" - - -@fixture -def keyring(): - set_keyring(NoKeyring()) - - -@fixture -def keyring_type(): - return "default" - - -@fixture -def config_data(config_path): - return load_config(config_path) - - -@fixture -def journal_name(): - return None - - -@fixture -def which_output_stream(): - return None - - -@fixture -def editor_input(): - return None - - -@fixture -def num_args(): - return None - - -@fixture -def parsed_output(): - return {"lang": None, "obj": None} - - -@fixture -def editor_state(): - return { - "command": "", - "intent": {"method": "r", "input": None}, - "tmpfile": {"name": None, "content": None}, - } - - -@fixture -def editor(editor_state): - def _mock_editor(editor_command): - tmpfile = editor_command[-1] - - editor_state["command"] = editor_command - editor_state["tmpfile"]["name"] = tmpfile - - Path(tmpfile).touch() - with open(tmpfile, editor_state["intent"]["method"]) as f: - # Touch the file so jrnl knows it was edited - if editor_state["intent"]["input"] != None: - f.write(editor_state["intent"]["input"]) - - file_content = f.read() - editor_state["tmpfile"]["content"] = file_content - - return _mock_editor - - -# ----- STEPS ----- # -@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 ""')) -@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 - ) - - -@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 - - if isinstance(num_args, int): - assert len(editor_state["command"]) == int(num_args) - - -@then(parse('the editor filename should end with "{suffix}"')) -def editor_filename_suffix(suffix, editor_state): - editor_filename = editor_state["tmpfile"]["name"] - - assert editor_state["tmpfile"]["name"].endswith(suffix), (editor_filename, suffix) - - -@then(parse('the editor file content should {comparison} "{str_value}"')) -@then(parse("the editor file content should {comparison} empty")) -@then(parse("the editor file content should {comparison}\n{str_value}")) -def contains_editor_file(comparison, str_value, editor_state): - content = editor_state["tmpfile"]["content"] - # content = f'\n"""\n{content}\n"""\n' - if comparison == "be": - assert content == str_value - elif comparison == "contain": - assert str_value in content - else: - assert False, f"Comparison '{comparison}' not supported" - - -@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 ""', 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('we use the password "{pw}" if prompted'), target_fixture="password") -def use_password_forever(pw): - return pw - - -@when(parse('we run "jrnl {command}" and {input_method}\n{user_input}')) -@when( - parsers.re( - 'we run "jrnl (?P[^"]+)" and (?Penter|pipe) "(?P[^"]+)"' - ) -) -@when(parse('we run "jrnl" and {input_method} "{user_input}"')) -@when(parse('we run "jrnl {command}"')) -@when('we run "jrnl "') -@when('we run "jrnl"') -def we_run( - command, - config_path, - user_input, - cli_run, - capsys, - password, - cache_dir, - editor, - keyring, - input_method, - mocks, -): - assert input_method in ["", "enter", "pipe"] - is_tty = input_method != "pipe" - - if cache_dir["exists"]: - command = command.format(cache_dir=cache_dir["path"]) - - args = split_args(command) - status = 0 - - if user_input: - user_input = user_input.splitlines() if is_tty else [user_input] - - if password: - password = password.splitlines() - - if not password and user_input: - password = user_input - - with ExitStack() as stack: - - stack.enter_context(patch("sys.argv", ["jrnl"] + args)) - - mock_stdin = stack.enter_context( - patch("sys.stdin.read", side_effect=user_input) - ) - stack.enter_context(patch("sys.stdin.isatty", return_value=is_tty)) - mock_input = stack.enter_context( - patch("builtins.input", side_effect=user_input) - ) - mock_getpass = stack.enter_context( - patch("getpass.getpass", side_effect=password) - ) - - if "datetime" in mocks: - stack.enter_context(mocks["datetime"]) - stack.enter_context(mocks["calendar_parse"]) - - # stack.enter_context(patch("datetime.datetime", new=mocks["datetime"])) - # stack.enter_context(patch("jrnl.time.__get_pdt_calendar", return_value=mocks["calendar_parse"])) - - stack.enter_context( - patch("jrnl.install.get_config_path", return_value=config_path) - ) - stack.enter_context( - patch("jrnl.config.get_config_path", return_value=config_path) - ) - mock_editor = stack.enter_context(patch("subprocess.call", side_effect=editor)) - - try: - cli(args) - except StopIteration: - # This happens when input is expected, but don't have any input left - pass - except SystemExit as e: - status = e.code - - captured = capsys.readouterr() - - cli_run["status"] = status - cli_run["stdout"] = captured.out - cli_run["stderr"] = captured.err - cli_run["mocks"] = { - "stdin": mock_stdin, - "input": mock_input, - "getpass": mock_getpass, - "editor": mock_editor, - } - - -@then("we should get no error") -def should_get_no_error(cli_run): - assert cli_run["status"] == 0, cli_run["status"] - - -@then(parse('the output should match "{regex}"')) -def output_should_match(regex, cli_run): - out = cli_run["stdout"] - matches = re.findall(regex, out) - assert matches, f"\nRegex didn't match:\n{regex}\n{str(out)}\n{str(matches)}" - - -@then(parse("the output should contain\n{expected_output}")) -@then(parse('the output should contain "{expected_output}"')) -@then('the output should contain ""') -@then(parse("the {which_output_stream} output should contain\n{expected_output}")) -@then(parse('the {which_output_stream} output should contain "{expected_output}"')) -def output_should_contain(expected_output, which_output_stream, cli_run): - assert expected_output - if which_output_stream is None: - assert (expected_output in cli_run["stdout"]) or ( - expected_output in cli_run["stderr"] - ) - - elif which_output_stream == "standard": - assert expected_output in cli_run["stdout"] - - elif which_output_stream == "error": - assert expected_output in cli_run["stderr"] - - else: - assert expected_output in cli_run[which_output_stream] - - -@then(parse("the output should not contain\n{expected_output}")) -@then(parse('the output should not contain "{expected_output}"')) -@then('the output should not contain ""') -def output_should_not_contain(expected_output, cli_run): - assert expected_output not in cli_run["stdout"] - - -@then(parse("the output should be\n{expected_output}")) -@then(parse('the output should be "{expected_output}"')) -@then('the output should be ""') -def output_should_be(expected_output, cli_run): - actual = cli_run["stdout"].strip() - expected = expected_output.strip() - assert expected == actual - - -@then("the output should be empty") -def output_should_be_empty(cli_run): - actual = cli_run["stdout"].strip() - assert actual == "" - - -@then('the output should contain the date ""') -def output_should_contain_date(date, cli_run): - assert date and date in cli_run["stdout"] - - -@then("the output should contain pyproject.toml version") -def output_should_contain_version(cli_run, toml_version): - out = cli_run["stdout"] - assert toml_version in out, toml_version - - -@then(parse('we should see the message "{text}"')) -def should_see_the_message(text, cli_run): - out = cli_run["stderr"] - assert text in out, [text, out] - - -def parse_should_or_should_not(should_or_should_not): - if should_or_should_not == "should": - return True - elif should_or_should_not == "should not": - return False - else: - raise Exception( - "should_or_should_not valid values are 'should' or 'should not'" - ) - - -@then( - parse( - 'the config for journal "{journal_name}" {should_or_should_not} contain "{some_yaml}"' - ) -) -@then( - parse( - 'the config for journal "{journal_name}" {should_or_should_not} contain\n{some_yaml}' - ) -) -@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): - we_should = parse_should_or_should_not(should_or_should_not) - - actual = config_data - if journal_name: - actual = actual["journals"][journal_name] - - expected = yaml.load(some_yaml, Loader=yaml.FullLoader) - - actual_slice = actual - if type(actual) is dict: - actual_slice = {key: actual.get(key, None) 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 - - -@then("we should not be prompted for a password") -def password_was_not_called(cli_run): - assert not cli_run["mocks"]["getpass"].called - - -@then(parse("the cache directory should contain the files\n{file_list}")) -def assert_dir_contains_files(file_list, cache_dir): - assert does_directory_contain_files(file_list, cache_dir["path"]) - - -@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") - - 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) - - assert not does_directory_contain_files( - scoped_config["journal"], "." - ), f'Journal "{journal_name}" does exist' - - -@when(parse('we change directory to "{directory_name}"')) -def when_we_change_directory(directory_name): - if not os.path.isdir(directory_name): - os.mkdir(directory_name) - - os.chdir(directory_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") - expected_path = scoped_config["journal"] - - contains_files = does_directory_contain_files(expected_path, ".") - - if should_or_should_not == "should": - assert contains_files - elif should_or_should_not == "should not": - assert not contains_files - else: - raise Exception( - "should_or_should_not valid values are 'should' or 'should not'" - ) - - -@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} - - -@then(parse('the content of file "{file_path}" in the cache should be\n{file_content}')) -def content_of_file_should_be(file_path, file_content, cache_dir): - assert cache_dir["exists"] - expected_content = file_content.strip().splitlines() - - with open(os.path.join(cache_dir["path"], file_path), "r") as f: - actual_content = f.read().strip().splitlines() - - for actual_line, expected_line in zip(actual_content, expected_content): - if actual_line.startswith("tags: ") and expected_line.startswith("tags: "): - assert_equal_tags_ignoring_order( - actual_line, expected_line, actual_content, expected_content - ) - else: - assert actual_line.strip() == expected_line.strip(), [ - [actual_line.strip(), expected_line.strip()], - [actual_content, expected_content], - ] - - -def assert_equal_tags_ignoring_order( - actual_line, expected_line, actual_content, expected_content -): - actual_tags = set(tag.strip() for tag in actual_line[len("tags: ") :].split(",")) - expected_tags = set( - tag.strip() for tag in expected_line[len("tags: ") :].split(",") - ) - assert actual_tags == expected_tags, [ - [actual_tags, expected_tags], - [expected_content, actual_content], - ] - - -@then(parse("the cache should contain the files\n{file_list}")) -def cache_dir_contains_files(file_list, cache_dir): - assert cache_dir["exists"] - - actual_files = os.listdir(cache_dir["path"]) - expected_files = file_list.split("\n") - - # sort to deal with inconsistent default file ordering on different OS's - actual_files.sort() - expected_files.sort() - - assert actual_files == expected_files, [actual_files, expected_files] - - -@then(parse("the output should be valid {language_name}")) -def assert_output_is_valid_language(cli_run, language_name): - language_name = language_name.upper() - if language_name == "XML": - xml_tree = ElementTree.fromstring(cli_run["stdout"]) - assert xml_tree, "Invalid XML" - elif language_name == "JSON": - assert json.loads(cli_run["stdout"]), "Invalid JSON" - else: - assert False, f"Language name {language_name} not recognized" - - -@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} - - -@then(parse('"{node_name}" in the parsed output should have {number:d} elements')) -def assert_parsed_output_item_count(node_name, number, parsed_output): - lang = parsed_output["lang"] - obj = parsed_output["obj"] - - if lang == "XML": - xml_node_names = (node.tag for node in obj) - assert node_name in xml_node_names, str(list(xml_node_names)) - - actual_entry_count = len(obj.find(node_name)) - assert actual_entry_count == number, actual_entry_count - - elif lang == "JSON": - my_obj = obj - - for node in node_name.split("."): - try: - my_obj = my_obj[int(node)] - except ValueError: - assert node in my_obj - my_obj = my_obj[node] - - assert len(my_obj) == number, len(my_obj) - - else: - assert False, f"Language name {lang} not recognized" - - -@then(parse('"{field_name}" in the parsed output should {comparison}\n{expected_keys}')) -def assert_output_field_content(field_name, comparison, expected_keys, parsed_output): - lang = parsed_output["lang"] - obj = parsed_output["obj"] - expected_keys = expected_keys.split("\n") - if len(expected_keys) == 1: - expected_keys = expected_keys[0] - - if lang == "XML": - xml_node_names = (node.tag for node in obj) - assert field_name in xml_node_names, str(list(xml_node_names)) - - if field_name == "tags": - actual_tags = set(t.attrib["name"] for t in obj.find("tags")) - assert set(actual_tags) == set(expected_keys), [ - actual_tags, - set(expected_keys), - ] - else: - assert False, "This test only works for tags in XML" - - elif lang == "JSON": - my_obj = obj - - for node in field_name.split("."): - try: - my_obj = my_obj[int(node)] - except ValueError: - assert node in my_obj, [my_obj.keys(), node] - my_obj = my_obj[node] - - if comparison == "be": - if type(my_obj) is str: - assert expected_keys == my_obj, [my_obj, expected_keys] - else: - assert set(expected_keys) == set(my_obj), [ - set(my_obj), - set(expected_keys), - ] - elif comparison == "contain": - if type(my_obj) is str: - assert expected_keys in my_obj, [my_obj, expected_keys] - else: - assert all(elem in my_obj for elem in expected_keys), [ - my_obj, - expected_keys, - ] - else: - assert False, f"Language name {lang} not recognized" - - -@then(parse('there should be {number:d} "{item}" elements')) -def count_elements(number, item, cli_run): - actual_output = cli_run["stdout"] - xml_tree = ElementTree.fromstring(actual_output) - assert len(xml_tree.findall(".//" + item)) == number diff --git a/tests/step_defs/fixtures.py b/tests/step_defs/fixtures.py new file mode 100644 index 00000000..a8e243ae --- /dev/null +++ b/tests/step_defs/fixtures.py @@ -0,0 +1,202 @@ +# Copyright (C) 2012-2021 jrnl contributors +# License: https://www.gnu.org/licenses/gpl-3.0.html + +import os +from collections import defaultdict +from keyring import backend +from keyring import set_keyring +from keyring import errors +from pathlib import Path +import tempfile + +from pytest import fixture +import toml + +from jrnl.config import load_config + + +# --- Keyring --- # +@fixture +def keyring(): + set_keyring(NoKeyring()) + + +@fixture +def keyring_type(): + return "default" + + +class TestKeyring(backend.KeyringBackend): + """A test keyring that just stores its values in a hash""" + + priority = 1 + keys = defaultdict(dict) + + def set_password(self, servicename, username, password): + self.keys[servicename][username] = password + + def get_password(self, servicename, username): + return self.keys[servicename].get(username) + + def delete_password(self, servicename, username): + self.keys[servicename][username] = None + + +class NoKeyring(backend.KeyringBackend): + """A keyring that simulated an environment with no keyring backend.""" + + priority = 2 + keys = defaultdict(dict) + + def set_password(self, servicename, username, password): + raise errors.NoKeyringError + + def get_password(self, servicename, username): + raise errors.NoKeyringError + + def delete_password(self, servicename, username): + raise errors.NoKeyringError + + +class FailedKeyring(backend.KeyringBackend): + """ A keyring that cannot be retrieved. """ + + priority = 2 + + def set_password(self, servicename, username, password): + raise errors.KeyringError + + def get_password(self, servicename, username): + raise errors.KeyringError + + def delete_password(self, servicename, username): + raise errors.KeyringError + + +# ----- Misc ----- # +@fixture +def cli_run(): + return {"status": 0, "stdout": None, "stderr": None} + + +@fixture +def mocks(): + return dict() + + +@fixture +def temp_dir(): + return tempfile.TemporaryDirectory() + + +@fixture +def working_dir(request): + return os.path.join(request.config.rootpath, "tests") + + +@fixture +def config_path(temp_dir): + os.chdir(temp_dir.name) + return temp_dir.name + "/jrnl.yaml" + + +@fixture +def toml_version(working_dir): + pyproject = os.path.join(working_dir, "..", "pyproject.toml") + pyproject_contents = toml.load(pyproject) + return pyproject_contents["tool"]["poetry"]["version"] + + +@fixture +def password(): + return "" + + +@fixture +def input_method(): + return "" + + +@fixture +def cache_dir(): + return {"exists": False, "path": ""} + + +@fixture +def str_value(): + return "" + + +@fixture +def command(): + return "" + + +@fixture +def should_not(): + return False + + +@fixture +def user_input(): + return "" + + +@fixture +def config_data(config_path): + return load_config(config_path) + + +@fixture +def journal_name(): + return None + + +@fixture +def which_output_stream(): + return None + + +@fixture +def editor_input(): + return None + + +@fixture +def num_args(): + return None + + +@fixture +def parsed_output(): + return {"lang": None, "obj": None} + + +@fixture +def editor_state(): + return { + "command": "", + "intent": {"method": "r", "input": None}, + "tmpfile": {"name": None, "content": None}, + } + + +@fixture +def editor(editor_state): + def _mock_editor(editor_command): + tmpfile = editor_command[-1] + + editor_state["command"] = editor_command + editor_state["tmpfile"]["name"] = tmpfile + + Path(tmpfile).touch() + with open(tmpfile, editor_state["intent"]["method"]) as f: + # Touch the file so jrnl knows it was edited + if editor_state["intent"]["input"] != None: + f.write(editor_state["intent"]["input"]) + + file_content = f.read() + editor_state["tmpfile"]["content"] = file_content + + return _mock_editor + diff --git a/tests/step_defs/given_steps.py b/tests/step_defs/given_steps.py new file mode 100644 index 00000000..8db8fa1c --- /dev/null +++ b/tests/step_defs/given_steps.py @@ -0,0 +1,133 @@ +# Copyright (C) 2012-2021 jrnl contributors +# License: https://www.gnu.org/licenses/gpl-3.0.html + +import json +import os +from datetime import datetime +from keyring import set_keyring +import random +import string +import shutil +from unittest.mock import patch +from unittest.mock import MagicMock +from xml.etree import ElementTree + +from jrnl import __version__ +from jrnl.time import __get_pdt_calendar + +from pytest_bdd import given +from pytest_bdd.parsers import parse +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 ""')) +@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 ""', 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('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} diff --git a/tests/step_defs/helpers.py b/tests/step_defs/helpers.py new file mode 100644 index 00000000..e2ea91c9 --- /dev/null +++ b/tests/step_defs/helpers.py @@ -0,0 +1,41 @@ +# Copyright (C) 2012-2021 jrnl contributors +# License: https://www.gnu.org/licenses/gpl-3.0.html + +import os + + + +def does_directory_contain_files(file_list, directory_path): + if not os.path.isdir(directory_path): + return False + + for file in file_list.split("\n"): + fullpath = directory_path + "/" + file + if not os.path.isfile(fullpath): + return False + + return True + + +def parse_should_or_should_not(should_or_should_not): + if should_or_should_not == "should": + return True + elif should_or_should_not == "should not": + return False + else: + raise Exception( + "should_or_should_not valid values are 'should' or 'should not'" + ) + + +def assert_equal_tags_ignoring_order( + actual_line, expected_line, actual_content, expected_content +): + actual_tags = set(tag.strip() for tag in actual_line[len("tags: ") :].split(",")) + expected_tags = set( + tag.strip() for tag in expected_line[len("tags: ") :].split(",") + ) + assert actual_tags == expected_tags, [ + [actual_tags, expected_tags], + [expected_content, actual_content], + ] diff --git a/tests/step_defs/then_steps.py b/tests/step_defs/then_steps.py new file mode 100644 index 00000000..4bcf1c56 --- /dev/null +++ b/tests/step_defs/then_steps.py @@ -0,0 +1,331 @@ +# Copyright (C) 2012-2021 jrnl contributors +# License: https://www.gnu.org/licenses/gpl-3.0.html + +import json +import os +import re +import yaml +from xml.etree import ElementTree + +from pytest_bdd import then +from pytest_bdd.parsers import parse + +from jrnl.config import scope_config + +from .helpers import parse_should_or_should_not +from .helpers import does_directory_contain_files +from .helpers import assert_equal_tags_ignoring_order + + +@then("we should get no error") +def should_get_no_error(cli_run): + assert cli_run["status"] == 0, cli_run["status"] + + +@then(parse('the output should match "{regex}"')) +def output_should_match(regex, cli_run): + out = cli_run["stdout"] + matches = re.findall(regex, out) + assert matches, f"\nRegex didn't match:\n{regex}\n{str(out)}\n{str(matches)}" + + +@then(parse("the output should contain\n{expected_output}")) +@then(parse('the output should contain "{expected_output}"')) +@then('the output should contain ""') +@then(parse("the {which_output_stream} output should contain\n{expected_output}")) +@then(parse('the {which_output_stream} output should contain "{expected_output}"')) +def output_should_contain(expected_output, which_output_stream, cli_run): + assert expected_output + if which_output_stream is None: + assert (expected_output in cli_run["stdout"]) or ( + expected_output in cli_run["stderr"] + ) + + elif which_output_stream == "standard": + assert expected_output in cli_run["stdout"] + + elif which_output_stream == "error": + assert expected_output in cli_run["stderr"] + + else: + assert expected_output in cli_run[which_output_stream] + + +@then(parse("the output should not contain\n{expected_output}")) +@then(parse('the output should not contain "{expected_output}"')) +@then('the output should not contain ""') +def output_should_not_contain(expected_output, cli_run): + assert expected_output not in cli_run["stdout"] + + +@then(parse("the output should be\n{expected_output}")) +@then(parse('the output should be "{expected_output}"')) +@then('the output should be ""') +def output_should_be(expected_output, cli_run): + actual = cli_run["stdout"].strip() + expected = expected_output.strip() + assert expected == actual + + +@then("the output should be empty") +def output_should_be_empty(cli_run): + actual = cli_run["stdout"].strip() + assert actual == "" + + +@then('the output should contain the date ""') +def output_should_contain_date(date, cli_run): + assert date and date in cli_run["stdout"] + + +@then("the output should contain pyproject.toml version") +def output_should_contain_version(cli_run, toml_version): + out = cli_run["stdout"] + assert toml_version in out, toml_version + + +@then(parse('we should see the message "{text}"')) +def should_see_the_message(text, cli_run): + out = cli_run["stderr"] + assert text in out, [text, out] + + +@then( + parse( + 'the config for journal "{journal_name}" {should_or_should_not} contain "{some_yaml}"' + ) +) +@then( + parse( + 'the config for journal "{journal_name}" {should_or_should_not} contain\n{some_yaml}' + ) +) +@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): + we_should = parse_should_or_should_not(should_or_should_not) + + actual = config_data + if journal_name: + actual = actual["journals"][journal_name] + + expected = yaml.load(some_yaml, Loader=yaml.FullLoader) + + actual_slice = actual + if type(actual) is dict: + actual_slice = {key: actual.get(key, None) 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 + + +@then("we should not be prompted for a password") +def password_was_not_called(cli_run): + assert not cli_run["mocks"]["getpass"].called + + +@then(parse("the cache directory should contain the files\n{file_list}")) +def assert_dir_contains_files(file_list, cache_dir): + assert does_directory_contain_files(file_list, cache_dir["path"]) + + +@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") + + 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) + + assert not does_directory_contain_files( + scoped_config["journal"], "." + ), f'Journal "{journal_name}" does exist' + + +@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") + expected_path = scoped_config["journal"] + + contains_files = does_directory_contain_files(expected_path, ".") + + if should_or_should_not == "should": + assert contains_files + elif should_or_should_not == "should not": + assert not contains_files + else: + raise Exception( + "should_or_should_not valid values are 'should' or 'should not'" + ) + + +@then(parse('the content of file "{file_path}" in the cache should be\n{file_content}')) +def content_of_file_should_be(file_path, file_content, cache_dir): + assert cache_dir["exists"] + expected_content = file_content.strip().splitlines() + + with open(os.path.join(cache_dir["path"], file_path), "r") as f: + actual_content = f.read().strip().splitlines() + + for actual_line, expected_line in zip(actual_content, expected_content): + if actual_line.startswith("tags: ") and expected_line.startswith("tags: "): + assert_equal_tags_ignoring_order( + actual_line, expected_line, actual_content, expected_content + ) + else: + assert actual_line.strip() == expected_line.strip(), [ + [actual_line.strip(), expected_line.strip()], + [actual_content, expected_content], + ] + + +@then(parse("the cache should contain the files\n{file_list}")) +def cache_dir_contains_files(file_list, cache_dir): + assert cache_dir["exists"] + + actual_files = os.listdir(cache_dir["path"]) + expected_files = file_list.split("\n") + + # sort to deal with inconsistent default file ordering on different OS's + actual_files.sort() + expected_files.sort() + + assert actual_files == expected_files, [actual_files, expected_files] + + +@then(parse("the output should be valid {language_name}")) +def assert_output_is_valid_language(cli_run, language_name): + language_name = language_name.upper() + if language_name == "XML": + xml_tree = ElementTree.fromstring(cli_run["stdout"]) + assert xml_tree, "Invalid XML" + elif language_name == "JSON": + assert json.loads(cli_run["stdout"]), "Invalid JSON" + else: + assert False, f"Language name {language_name} not recognized" + + +@then(parse('"{node_name}" in the parsed output should have {number:d} elements')) +def assert_parsed_output_item_count(node_name, number, parsed_output): + lang = parsed_output["lang"] + obj = parsed_output["obj"] + + if lang == "XML": + xml_node_names = (node.tag for node in obj) + assert node_name in xml_node_names, str(list(xml_node_names)) + + actual_entry_count = len(obj.find(node_name)) + assert actual_entry_count == number, actual_entry_count + + elif lang == "JSON": + my_obj = obj + + for node in node_name.split("."): + try: + my_obj = my_obj[int(node)] + except ValueError: + assert node in my_obj + my_obj = my_obj[node] + + assert len(my_obj) == number, len(my_obj) + + else: + assert False, f"Language name {lang} not recognized" + + +@then(parse('"{field_name}" in the parsed output should {comparison}\n{expected_keys}')) +def assert_output_field_content(field_name, comparison, expected_keys, parsed_output): + lang = parsed_output["lang"] + obj = parsed_output["obj"] + expected_keys = expected_keys.split("\n") + if len(expected_keys) == 1: + expected_keys = expected_keys[0] + + if lang == "XML": + xml_node_names = (node.tag for node in obj) + assert field_name in xml_node_names, str(list(xml_node_names)) + + if field_name == "tags": + actual_tags = set(t.attrib["name"] for t in obj.find("tags")) + assert set(actual_tags) == set(expected_keys), [ + actual_tags, + set(expected_keys), + ] + else: + assert False, "This test only works for tags in XML" + + elif lang == "JSON": + my_obj = obj + + for node in field_name.split("."): + try: + my_obj = my_obj[int(node)] + except ValueError: + assert node in my_obj, [my_obj.keys(), node] + my_obj = my_obj[node] + + if comparison == "be": + if type(my_obj) is str: + assert expected_keys == my_obj, [my_obj, expected_keys] + else: + assert set(expected_keys) == set(my_obj), [ + set(my_obj), + set(expected_keys), + ] + elif comparison == "contain": + if type(my_obj) is str: + assert expected_keys in my_obj, [my_obj, expected_keys] + else: + assert all(elem in my_obj for elem in expected_keys), [ + my_obj, + expected_keys, + ] + else: + assert False, f"Language name {lang} not recognized" + + +@then(parse('there should be {number:d} "{item}" elements')) +def count_elements(number, item, cli_run): + actual_output = cli_run["stdout"] + xml_tree = ElementTree.fromstring(actual_output) + 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 + + if isinstance(num_args, int): + assert len(editor_state["command"]) == int(num_args) + + +@then(parse('the editor filename should end with "{suffix}"')) +def editor_filename_suffix(suffix, editor_state): + editor_filename = editor_state["tmpfile"]["name"] + + assert editor_state["tmpfile"]["name"].endswith(suffix), (editor_filename, suffix) + + +@then(parse('the editor file content should {comparison} "{str_value}"')) +@then(parse("the editor file content should {comparison} empty")) +@then(parse("the editor file content should {comparison}\n{str_value}")) +def contains_editor_file(comparison, str_value, editor_state): + content = editor_state["tmpfile"]["content"] + # content = f'\n"""\n{content}\n"""\n' + if comparison == "be": + assert content == str_value + elif comparison == "contain": + assert str_value in content + else: + assert False, f"Comparison '{comparison}' not supported" diff --git a/tests/step_defs/when_steps.py b/tests/step_defs/when_steps.py new file mode 100644 index 00000000..a80d7525 --- /dev/null +++ b/tests/step_defs/when_steps.py @@ -0,0 +1,113 @@ +# Copyright (C) 2012-2021 jrnl contributors +# License: https://www.gnu.org/licenses/gpl-3.0.html + +import os +from contextlib import ExitStack +from unittest.mock import patch + +from pytest_bdd import when +from pytest_bdd.parsers import parse +from pytest_bdd import parsers + +from jrnl.cli import cli +from jrnl.os_compat import split_args + + +@when(parse('we change directory to "{directory_name}"')) +def when_we_change_directory(directory_name): + if not os.path.isdir(directory_name): + os.mkdir(directory_name) + + os.chdir(directory_name) + + +@when(parse('we run "jrnl {command}" and {input_method}\n{user_input}')) +@when( + parsers.re( + 'we run "jrnl (?P[^"]+)" and (?Penter|pipe) "(?P[^"]+)"' + ) +) +@when(parse('we run "jrnl" and {input_method} "{user_input}"')) +@when(parse('we run "jrnl {command}"')) +@when('we run "jrnl "') +@when('we run "jrnl"') +def we_run( + command, + config_path, + user_input, + cli_run, + capsys, + password, + cache_dir, + editor, + keyring, + input_method, + mocks, +): + assert input_method in ["", "enter", "pipe"] + is_tty = input_method != "pipe" + + if cache_dir["exists"]: + command = command.format(cache_dir=cache_dir["path"]) + + args = split_args(command) + status = 0 + + if user_input: + user_input = user_input.splitlines() if is_tty else [user_input] + + if password: + password = password.splitlines() + + if not password and user_input: + password = user_input + + with ExitStack() as stack: + + stack.enter_context(patch("sys.argv", ["jrnl"] + args)) + + mock_stdin = stack.enter_context( + patch("sys.stdin.read", side_effect=user_input) + ) + stack.enter_context(patch("sys.stdin.isatty", return_value=is_tty)) + mock_input = stack.enter_context( + patch("builtins.input", side_effect=user_input) + ) + mock_getpass = stack.enter_context( + patch("getpass.getpass", side_effect=password) + ) + + if "datetime" in mocks: + stack.enter_context(mocks["datetime"]) + stack.enter_context(mocks["calendar_parse"]) + + # stack.enter_context(patch("datetime.datetime", new=mocks["datetime"])) + # stack.enter_context(patch("jrnl.time.__get_pdt_calendar", return_value=mocks["calendar_parse"])) + + stack.enter_context( + patch("jrnl.install.get_config_path", return_value=config_path) + ) + stack.enter_context( + patch("jrnl.config.get_config_path", return_value=config_path) + ) + mock_editor = stack.enter_context(patch("subprocess.call", side_effect=editor)) + + try: + cli(args) + except StopIteration: + # This happens when input is expected, but don't have any input left + pass + except SystemExit as e: + status = e.code + + captured = capsys.readouterr() + + cli_run["status"] = status + cli_run["stdout"] = captured.out + cli_run["stderr"] = captured.err + cli_run["mocks"] = { + "stdin": mock_stdin, + "input": mock_input, + "getpass": mock_getpass, + "editor": mock_editor, + } From cdad0d62896ff3be496ed4a76e970b9b00334554 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Thu, 24 Jun 2021 09:38:00 -0700 Subject: [PATCH 151/215] Replace pyflakes with flake8 for linting --- Makefile | 2 +- jrnl/DayOneJournal.py | 14 ++--- jrnl/Journal.py | 5 +- jrnl/exception.py | 27 ++++---- poetry.lock | 110 ++++++++++++++++++++++++++------- pyproject.toml | 6 +- tests/step_defs/conftest.py | 14 +++-- tests/step_defs/fixtures.py | 13 ++-- tests/step_defs/given_steps.py | 13 ++-- tests/step_defs/helpers.py | 1 - tests/step_defs/then_steps.py | 6 +- tests/step_defs/when_steps.py | 4 +- tests/unit/test_color.py | 3 +- tests/unit/test_display.py | 6 +- tests/unit/test_export.py | 4 +- tests/unit/test_install.py | 5 +- tests/unit/test_os_compat.py | 3 +- tests/unit/test_override.py | 14 ++--- tests/unit/test_parse_args.py | 4 +- 19 files changed, 164 insertions(+), 90 deletions(-) diff --git a/Makefile b/Makefile index 454702c6..a04a9c86 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ format: ## Format files to match style lint: ## Check style with various tools poetry check - poetry run pyflakes jrnl tests + poetry run pflake8 jrnl tests poetry run black --check --diff . unit: # unit tests diff --git a/jrnl/DayOneJournal.py b/jrnl/DayOneJournal.py index 00271875..01b934e5 100644 --- a/jrnl/DayOneJournal.py +++ b/jrnl/DayOneJournal.py @@ -78,35 +78,35 @@ class DayOne(Journal.Journal): entry.creator_device_agent = dict_entry["Creator"][ "Device Agent" ] - except: + except: # noqa: E722 pass try: entry.creator_generation_date = dict_entry["Creator"][ "Generation Date" ] - except: + except: # noqa: E722 entry.creator_generation_date = date try: entry.creator_host_name = dict_entry["Creator"]["Host Name"] - except: + except: # noqa: E722 pass try: entry.creator_os_agent = dict_entry["Creator"]["OS Agent"] - except: + except: # noqa: E722 pass try: entry.creator_software_agent = dict_entry["Creator"][ "Software Agent" ] - except: + except: # noqa: E722 pass try: entry.location = dict_entry["Location"] - except: + except: # noqa: E722 pass try: entry.weather = dict_entry["Weather"] - except: + except: # noqa: E722 pass self.entries.append(entry) self.sort() diff --git a/jrnl/Journal.py b/jrnl/Journal.py index 181d85c4..6d3c6886 100644 --- a/jrnl/Journal.py +++ b/jrnl/Journal.py @@ -220,7 +220,10 @@ class Journal: # If strict mode is on, all tags have to be present in entry tagged = self.search_tags.issubset if strict else self.search_tags.intersection - excluded = lambda tags: len([tag for tag in tags if tag in excluded_tags]) > 0 + + def excluded(tags): + return 0 < len([tag for tag in tags if tag in excluded_tags]) + if contains: contains_lower = contains.casefold() diff --git a/jrnl/exception.py b/jrnl/exception.py index cb6672d7..07bf9023 100644 --- a/jrnl/exception.py +++ b/jrnl/exception.py @@ -22,25 +22,24 @@ class JrnlError(Exception): def _get_error_message(self, **kwargs): error_messages = { - "ConfigDirectoryIsFile": textwrap.dedent( - """ + "ConfigDirectoryIsFile": """ 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. - """ - ), - "LineWrapTooSmallForDateFormat": textwrap.dedent( - """ - The provided linewrap value of {config_linewrap} is too small by {columns} columns - to display the timestamps in the configured time format for journal {journal}. + """, + "LineWrapTooSmallForDateFormat": """ + The provided linewrap value of {config_linewrap} is too small by + {columns} columns to display the timestamps in the configured time + format for journal {journal}. - You can avoid this error by specifying a linewrap value that is larger by at least {columns} in the configuration file or by using --config-override at the command line - """ - ), + You can avoid this error by specifying a linewrap value that is larger + by at least {columns} in the configuration file or by using + --config-override at the command line + """, } - return error_messages[self.error_type].format(**kwargs) - - pass + msg = error_messages[self.error_type].format(**kwargs) + msg = textwrap.dedent(msg) + return msg diff --git a/poetry.lock b/poetry.lock index 65670545..50b41e3c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -41,7 +41,7 @@ test = ["coverage", "flake8", "pexpect", "wheel"] [[package]] name = "asteval" -version = "0.9.23" +version = "0.9.25" description = "Safe, minimalistic evaluator of python expression using ast module" category = "main" optional = false @@ -176,6 +176,20 @@ category = "dev" optional = false python-versions = ">=3.5" +[[package]] +name = "flake8" +version = "3.9.2" +description = "the modular source code checker: pep8 pyflakes and co" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[package.dependencies] +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.7.0,<2.8.0" +pyflakes = ">=2.3.0,<2.4.0" + [[package]] name = "ghp-import" version = "2.0.1" @@ -237,7 +251,7 @@ toml = {version = ">=0.10.2", markers = "python_version > \"3.6\""} [[package]] name = "ipython" -version = "7.24.1" +version = "7.25.0" description = "IPython: Productive Interactive Computing" category = "dev" optional = false @@ -381,6 +395,14 @@ python-versions = ">=3.5" [package.dependencies] traitlets = "*" +[[package]] +name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "mergedeep" version = "1.3.4" @@ -543,6 +565,14 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "pycodestyle" +version = "2.7.0" +description = "Python style guide checker" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + [[package]] name = "pycparser" version = "2.20" @@ -575,6 +605,18 @@ category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "pyproject-flake8" +version = "0.0.1a2" +description = "pyproject-flake8 (`pflake8`), a monkey patching wrapper to connect flake8 with pyproject.toml configuration" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +flake8 = "*" +toml = "*" + [[package]] name = "pytest" version = "6.2.4" @@ -775,7 +817,7 @@ pytz = "*" [[package]] name = "watchdog" -version = "2.1.2" +version = "2.1.3" description = "Filesystem events monitoring" category = "dev" optional = false @@ -832,7 +874,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pyt [metadata] lock-version = "1.1" python-versions = ">=3.7.0, <3.10" -content-hash = "d9a47064f2050860c955a0871b2bd8899c2f24aaf6482f6a742316fd1fd95ba3" +content-hash = "5be8c38e248b64ff4f2eacf253411b57c91352523c40674f1dec6d8c304996c2" [metadata.files] ansiwrap = [ @@ -852,7 +894,7 @@ argcomplete = [ {file = "argcomplete-1.12.3.tar.gz", hash = "sha256:2c7dbffd8c045ea534921e63b0be6fe65e88599990d8dc408ac8c542b72a5445"}, ] asteval = [ - {file = "asteval-0.9.23.tar.gz", hash = "sha256:f5096a924b1d2f147e70327245d95fc8f534dbe94277b6828ce2a8c049d3a438"}, + {file = "asteval-0.9.25.tar.gz", hash = "sha256:bea22b7d8fa16bcba95ebc72052ae5d8ca97114c9959bb47f8b8eebf30e4342f"}, ] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, @@ -939,6 +981,10 @@ decorator = [ {file = "decorator-5.0.9-py3-none-any.whl", hash = "sha256:6e5c199c16f7a9f0e3a61a4a54b3d27e7dad0dbdde92b944426cb20914376323"}, {file = "decorator-5.0.9.tar.gz", hash = "sha256:72ecfba4320a893c53f9706bebb2d55c270c1e51a28789361aa93e4a21319ed5"}, ] +flake8 = [ + {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, + {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, +] ghp-import = [ {file = "ghp-import-2.0.1.tar.gz", hash = "sha256:753de2eace6e0f7d4edfb3cce5e3c3b98cd52aadb80163303d1d036bda7b4483"}, ] @@ -957,8 +1003,8 @@ ipdb = [ {file = "ipdb-0.13.9.tar.gz", hash = "sha256:951bd9a64731c444fd907a5ce268543020086a697f6be08f7cc2c9a752a278c5"}, ] ipython = [ - {file = "ipython-7.24.1-py3-none-any.whl", hash = "sha256:d513e93327cf8657d6467c81f1f894adc125334ffe0e4ddd1abbb1c78d828703"}, - {file = "ipython-7.24.1.tar.gz", hash = "sha256:9bc24a99f5d19721fb8a2d1408908e9c0520a17fff2233ffe82620847f17f1b6"}, + {file = "ipython-7.25.0-py3-none-any.whl", hash = "sha256:aa21412f2b04ad1a652e30564fff6b4de04726ce875eab222c8430edc6db383a"}, + {file = "ipython-7.25.0.tar.gz", hash = "sha256:54bbd1fe3882457aaf28ae060a5ccdef97f212a741754e420028d4ec5c2291dc"}, ] ipython-genutils = [ {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, @@ -1027,6 +1073,10 @@ matplotlib-inline = [ {file = "matplotlib-inline-0.1.2.tar.gz", hash = "sha256:f41d5ff73c9f5385775d5c0bc13b424535c8402fe70ea8210f93e11f3683993e"}, {file = "matplotlib_inline-0.1.2-py3-none-any.whl", hash = "sha256:5cf1176f554abb4fa98cb362aa2b55c500147e4bdbb07e3fda359143e1da0811"}, ] +mccabe = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] mergedeep = [ {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, @@ -1086,6 +1136,10 @@ py = [ {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, ] +pycodestyle = [ + {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, + {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, +] pycparser = [ {file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"}, {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"}, @@ -1102,6 +1156,10 @@ pyparsing = [ {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] +pyproject-flake8 = [ + {file = "pyproject-flake8-0.0.1a2.tar.gz", hash = "sha256:bdeca37f78ecd34bd64a49d3657d53d099f5445831071a31c46e1fe20cd61461"}, + {file = "pyproject_flake8-0.0.1a2-py2.py3-none-any.whl", hash = "sha256:e61ed1dc088e9f9f8a7170967ac4ec135acfef3a59ab9738c7b58cc11f294a7e"}, +] pytest = [ {file = "pytest-6.2.4-py3-none-any.whl", hash = "sha256:91ef2131a9bd6be8f76f1f08eac5c5317221d6ad1e143ae03894b862e8976890"}, {file = "pytest-6.2.4.tar.gz", hash = "sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b"}, @@ -1264,23 +1322,27 @@ tzlocal = [ {file = "tzlocal-2.1.tar.gz", hash = "sha256:643c97c5294aedc737780a49d9df30889321cbe1204eac2c2ec6134035a92e44"}, ] watchdog = [ - {file = "watchdog-2.1.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:581e3548159fe7d2a9f377a1fbcb41bdcee46849cca8ab803c7ac2e5e04ec77c"}, - {file = "watchdog-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:edcd9ef3fd460bb8a98eb1fcf99941e9fd9f275f45f1a82cb1359ec92975d647"}, - {file = "watchdog-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d34ce2261f118ecd57eedeef95fc2a495fc4a40b3ed7b3bf0bd7a8ccc1ab4f8f"}, - {file = "watchdog-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:668391e6c32742d76e5be5db6bf95c455fa4b3d11e76a77c13b39bccb3a47a72"}, - {file = "watchdog-2.1.2-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6ef9fe57162c4c361692620e1d9167574ba1975ee468b24051ca11c9bba6438e"}, - {file = "watchdog-2.1.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:58ebb1095ee493008a7789d47dd62e4999505d82be89fc884d473086fccc6ebd"}, - {file = "watchdog-2.1.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:91387ee2421f30b75f7ff632c9d48f76648e56bf346a7c805c0a34187a93aab4"}, - {file = "watchdog-2.1.2-py3-none-manylinux2014_armv7l.whl", hash = "sha256:a6471517315a8541a943c00b45f1d252e36898a3ae963d2d52509b89a50cb2b9"}, - {file = "watchdog-2.1.2-py3-none-manylinux2014_i686.whl", hash = "sha256:a42e6d652f820b2b94cd03156c62559a2ea68d476476dfcd77d931e7f1012d4a"}, - {file = "watchdog-2.1.2-py3-none-manylinux2014_ppc64.whl", hash = "sha256:3d6405681471ebe0beb3aa083998c4870e48b57f8afdb45ea1b5957cc5cf1014"}, - {file = "watchdog-2.1.2-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:598d772beeaf9c98d0df946fbabf0c8365dd95ea46a250c224c725fe0c4730bc"}, - {file = "watchdog-2.1.2-py3-none-manylinux2014_s390x.whl", hash = "sha256:4b219d46d89cfa49af1d73175487c14a318a74cb8c5442603fd13c6a5b418c86"}, - {file = "watchdog-2.1.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:188145185c08c73c56f1478ccf1f0f0f85101191439679b35b6b100886ce0b39"}, - {file = "watchdog-2.1.2-py3-none-win32.whl", hash = "sha256:255a32d44bbbe62e52874ff755e2eefe271b150e0ec240ad7718a62a7a7a73c4"}, - {file = "watchdog-2.1.2-py3-none-win_amd64.whl", hash = "sha256:1a62a4671796dc93d1a7262286217d9e75823c63d4c42782912d39a506d30046"}, - {file = "watchdog-2.1.2-py3-none-win_ia64.whl", hash = "sha256:104266a778906ae0e971368d368a65c4cd032a490a9fca5ba0b78c6c7ae11720"}, - {file = "watchdog-2.1.2.tar.gz", hash = "sha256:0237db4d9024859bea27d0efb59fe75eef290833fd988b8ead7a879b0308c2db"}, + {file = "watchdog-2.1.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9628f3f85375a17614a2ab5eac7665f7f7be8b6b0a2a228e6f6a2e91dd4bfe26"}, + {file = "watchdog-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:acc4e2d5be6f140f02ee8590e51c002829e2c33ee199036fcd61311d558d89f4"}, + {file = "watchdog-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:85b851237cf3533fabbc034ffcd84d0fa52014b3121454e5f8b86974b531560c"}, + {file = "watchdog-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a12539ecf2478a94e4ba4d13476bb2c7a2e0a2080af2bb37df84d88b1b01358a"}, + {file = "watchdog-2.1.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6fe9c8533e955c6589cfea6f3f0a1a95fb16867a211125236c82e1815932b5d7"}, + {file = "watchdog-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d9456f0433845e7153b102fffeb767bde2406b76042f2216838af3b21707894e"}, + {file = "watchdog-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fd8c595d5a93abd441ee7c5bb3ff0d7170e79031520d113d6f401d0cf49d7c8f"}, + {file = "watchdog-2.1.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0bcfe904c7d404eb6905f7106c54873503b442e8e918cc226e1828f498bdc0ca"}, + {file = "watchdog-2.1.3-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bf84bd94cbaad8f6b9cbaeef43080920f4cb0e61ad90af7106b3de402f5fe127"}, + {file = "watchdog-2.1.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b8ddb2c9f92e0c686ea77341dcb58216fa5ff7d5f992c7278ee8a392a06e86bb"}, + {file = "watchdog-2.1.3-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8805a5f468862daf1e4f4447b0ccf3acaff626eaa57fbb46d7960d1cf09f2e6d"}, + {file = "watchdog-2.1.3-py3-none-manylinux2014_armv7l.whl", hash = "sha256:3e305ea2757f81d8ebd8559d1a944ed83e3ab1bdf68bcf16ec851b97c08dc035"}, + {file = "watchdog-2.1.3-py3-none-manylinux2014_i686.whl", hash = "sha256:431a3ea70b20962e6dee65f0eeecd768cd3085ea613ccb9b53c8969de9f6ebd2"}, + {file = "watchdog-2.1.3-py3-none-manylinux2014_ppc64.whl", hash = "sha256:e4929ac2aaa2e4f1a30a36751160be391911da463a8799460340901517298b13"}, + {file = "watchdog-2.1.3-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:201cadf0b8c11922f54ec97482f95b2aafca429c4c3a4bb869a14f3c20c32686"}, + {file = "watchdog-2.1.3-py3-none-manylinux2014_s390x.whl", hash = "sha256:3a7d242a7963174684206093846537220ee37ba9986b824a326a8bb4ef329a33"}, + {file = "watchdog-2.1.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:54e057727dd18bd01a3060dbf5104eb5a495ca26316487e0f32a394fd5fe725a"}, + {file = "watchdog-2.1.3-py3-none-win32.whl", hash = "sha256:b5fc5c127bad6983eecf1ad117ab3418949f18af9c8758bd10158be3647298a9"}, + {file = "watchdog-2.1.3-py3-none-win_amd64.whl", hash = "sha256:44acad6f642996a2b50bb9ce4fb3730dde08f23e79e20cd3d8e2a2076b730381"}, + {file = "watchdog-2.1.3-py3-none-win_ia64.whl", hash = "sha256:0bcdf7b99b56a3ae069866c33d247c9994ffde91b620eaf0306b27e099bd1ae0"}, + {file = "watchdog-2.1.3.tar.gz", hash = "sha256:e5236a8e8602ab6db4b873664c2d356c365ab3cac96fbdec4970ad616415dd45"}, ] wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, diff --git a/pyproject.toml b/pyproject.toml index 2719b954..36bc3d13 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,12 +48,12 @@ behave = "^1.2" mkdocs = "^1.0" black = {version = "^21.5b2",allow-prereleases = true} toml = ">=0.10" -pyflakes = ">=2.2.0" pytest = ">=6.2" pytest-bdd = "^4.0.1" yq = ">=2.11" ipdb = ">=0.13" pytest-clarity = "^0.3.0-alpha.0" +pyproject-flake8 = "^0.0.1-alpha.2" [tool.poetry.scripts] jrnl = 'jrnl.cli:cli' @@ -84,6 +84,10 @@ filterwarnings = [ "ignore:[WinError 5].*" ] +[tool.flake8] +# ignore formatting warnings and errors because we use Black to autoformat +extend-ignore = "E101,E111,E114,E115,E116,E117,E12,E13,E2,E3,E401,E5,E70,W1,W2,W3,W5" + [build-system] requires = ["poetry>=1.1"] build-backend = "poetry.masonry.api" diff --git a/tests/step_defs/conftest.py b/tests/step_defs/conftest.py index d73fcec4..a3021972 100644 --- a/tests/step_defs/conftest.py +++ b/tests/step_defs/conftest.py @@ -1,13 +1,17 @@ # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html -from jrnl.os_compat import on_windows from pytest import mark -from .fixtures import * -from .given_steps import * -from .when_steps import * -from .then_steps import * +from jrnl.os_compat import on_windows + + +pytest_plugins = [ + "tests.step_defs.fixtures", + "tests.step_defs.given_steps", + "tests.step_defs.when_steps", + "tests.step_defs.then_steps", +] def pytest_bdd_apply_tag(tag, function): diff --git a/tests/step_defs/fixtures.py b/tests/step_defs/fixtures.py index a8e243ae..a93a7e43 100644 --- a/tests/step_defs/fixtures.py +++ b/tests/step_defs/fixtures.py @@ -1,14 +1,14 @@ # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html -import os from collections import defaultdict -from keyring import backend -from keyring import set_keyring -from keyring import errors +import os from pathlib import Path import tempfile +from keyring import backend +from keyring import errors +from keyring import set_keyring from pytest import fixture import toml @@ -59,7 +59,7 @@ class NoKeyring(backend.KeyringBackend): class FailedKeyring(backend.KeyringBackend): - """ A keyring that cannot be retrieved. """ + """A keyring that cannot be retrieved.""" priority = 2 @@ -192,11 +192,10 @@ def editor(editor_state): Path(tmpfile).touch() with open(tmpfile, editor_state["intent"]["method"]) as f: # Touch the file so jrnl knows it was edited - if editor_state["intent"]["input"] != None: + if editor_state["intent"]["input"] is not None: f.write(editor_state["intent"]["input"]) file_content = f.read() editor_state["tmpfile"]["content"] = file_content return _mock_editor - diff --git a/tests/step_defs/given_steps.py b/tests/step_defs/given_steps.py index 8db8fa1c..649d44c5 100644 --- a/tests/step_defs/given_steps.py +++ b/tests/step_defs/given_steps.py @@ -1,22 +1,23 @@ # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html +from datetime import datetime import json import os -from datetime import datetime -from keyring import set_keyring import random -import string import shutil -from unittest.mock import patch +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 pytest_bdd import given -from pytest_bdd.parsers import parse from .fixtures import FailedKeyring from .fixtures import TestKeyring diff --git a/tests/step_defs/helpers.py b/tests/step_defs/helpers.py index e2ea91c9..7d089597 100644 --- a/tests/step_defs/helpers.py +++ b/tests/step_defs/helpers.py @@ -4,7 +4,6 @@ import os - def does_directory_contain_files(file_list, directory_path): if not os.path.isdir(directory_path): return False diff --git a/tests/step_defs/then_steps.py b/tests/step_defs/then_steps.py index 4bcf1c56..b56c203f 100644 --- a/tests/step_defs/then_steps.py +++ b/tests/step_defs/then_steps.py @@ -4,17 +4,17 @@ import json import os import re -import yaml from xml.etree import ElementTree from pytest_bdd import then from pytest_bdd.parsers import parse +import yaml from jrnl.config import scope_config -from .helpers import parse_should_or_should_not -from .helpers import does_directory_contain_files from .helpers import assert_equal_tags_ignoring_order +from .helpers import does_directory_contain_files +from .helpers import parse_should_or_should_not @then("we should get no error") diff --git a/tests/step_defs/when_steps.py b/tests/step_defs/when_steps.py index a80d7525..2e72173b 100644 --- a/tests/step_defs/when_steps.py +++ b/tests/step_defs/when_steps.py @@ -1,13 +1,13 @@ # Copyright (C) 2012-2021 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html -import os from contextlib import ExitStack +import os from unittest.mock import patch +from pytest_bdd import parsers from pytest_bdd import when from pytest_bdd.parsers import parse -from pytest_bdd import parsers from jrnl.cli import cli from jrnl.os_compat import split_args diff --git a/tests/unit/test_color.py b/tests/unit/test_color.py index 14dc7938..527b8e89 100644 --- a/tests/unit/test_color.py +++ b/tests/unit/test_color.py @@ -1,7 +1,8 @@ +from colorama import Fore +from colorama import Style import pytest from jrnl.color import colorize -from colorama import Fore, Style @pytest.fixture() diff --git a/tests/unit/test_display.py b/tests/unit/test_display.py index 72a9c451..921d1631 100644 --- a/tests/unit/test_display.py +++ b/tests/unit/test_display.py @@ -1,7 +1,9 @@ import argparse -import jrnl -import pytest from unittest import mock + +import pytest + +import jrnl from jrnl.jrnl import _display_search_results diff --git a/tests/unit/test_export.py b/tests/unit/test_export.py index 0f494f79..8bc1b410 100644 --- a/tests/unit/test_export.py +++ b/tests/unit/test_export.py @@ -1,8 +1,8 @@ +import pytest + from jrnl.exception import JrnlError from jrnl.plugins.fancy_exporter import check_provided_linewrap_viability -import pytest - @pytest.fixture() def datestr(): diff --git a/tests/unit/test_install.py b/tests/unit/test_install.py index 31ec150c..bc36b927 100644 --- a/tests/unit/test_install.py +++ b/tests/unit/test_install.py @@ -1,6 +1,7 @@ -from unittest import mock -import pytest import sys +from unittest import mock + +import pytest @pytest.mark.filterwarnings( diff --git a/tests/unit/test_os_compat.py b/tests/unit/test_os_compat.py index f7c058f1..02d54716 100644 --- a/tests/unit/test_os_compat.py +++ b/tests/unit/test_os_compat.py @@ -1,8 +1,9 @@ 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 on_windows from jrnl.os_compat import split_args diff --git a/tests/unit/test_override.py b/tests/unit/test_override.py index 32ec0595..d22709f4 100644 --- a/tests/unit/test_override.py +++ b/tests/unit/test_override.py @@ -1,12 +1,10 @@ import pytest -from jrnl.override import ( - apply_overrides, - _recursively_apply, - _get_config_node, - _get_key_and_value_from_pair, - _convert_dots_to_list, -) +from jrnl.override import _convert_dots_to_list +from jrnl.override import _get_config_node +from jrnl.override import _get_key_and_value_from_pair +from jrnl.override import _recursively_apply +from jrnl.override import apply_overrides @pytest.fixture() @@ -56,7 +54,7 @@ def test_recursively_apply(): 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 + assert _get_config_node(minimal_config, "display_format") is None def test_get_kv_from_pair(): diff --git a/tests/unit/test_parse_args.py b/tests/unit/test_parse_args.py index 4b140fc1..0725d33d 100644 --- a/tests/unit/test_parse_args.py +++ b/tests/unit/test_parse_args.py @@ -283,10 +283,10 @@ class TestDeserialization: assert cfg["linewrap"] == 23 cfg = make_yaml_valid_dict(["encrypt", "false"]) - assert cfg["encrypt"] == False + assert cfg["encrypt"] is 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 + assert cfg["highlight"] is True From f99411f2f96620ae9683482c769f3d4f39083c8d Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 3 Jul 2021 14:52:27 -0700 Subject: [PATCH 152/215] move some files around because pytest is being weird --- Makefile | 10 +- poetry.lock | 114 +++--- tests/{ => bdd}/features/build.feature | 0 tests/{ => bdd}/features/core.feature | 0 tests/{ => bdd}/features/datetime.feature | 0 tests/{ => bdd}/features/delete.feature | 0 tests/{ => bdd}/features/encrypt.feature | 0 tests/{ => bdd}/features/file_storage.feature | 0 tests/{ => bdd}/features/format.feature | 0 tests/{ => bdd}/features/import.feature | 0 .../features/multiple_journals.feature | 0 tests/{ => bdd}/features/password.feature | 0 tests/{ => bdd}/features/search.feature | 0 tests/{ => bdd}/features/star.feature | 0 tests/{ => bdd}/features/tag.feature | 0 tests/{ => bdd}/features/upgrade.feature | 0 tests/{ => bdd}/features/write.feature | 0 tests/bdd/test_features.py | 17 + tests/{step_defs => }/conftest.py | 8 +- tests/step_defs/__init__.py | 3 - tests/step_defs/fixtures.py | 201 ----------- tests/step_defs/given_steps.py | 134 ------- tests/step_defs/helpers.py | 40 --- tests/step_defs/test_features.py | 17 - tests/step_defs/then_steps.py | 331 ------------------ tests/step_defs/when_steps.py | 113 ------ 26 files changed, 81 insertions(+), 907 deletions(-) rename tests/{ => bdd}/features/build.feature (100%) rename tests/{ => bdd}/features/core.feature (100%) rename tests/{ => bdd}/features/datetime.feature (100%) rename tests/{ => bdd}/features/delete.feature (100%) rename tests/{ => bdd}/features/encrypt.feature (100%) rename tests/{ => bdd}/features/file_storage.feature (100%) rename tests/{ => bdd}/features/format.feature (100%) rename tests/{ => bdd}/features/import.feature (100%) rename tests/{ => bdd}/features/multiple_journals.feature (100%) rename tests/{ => bdd}/features/password.feature (100%) rename tests/{ => bdd}/features/search.feature (100%) rename tests/{ => bdd}/features/star.feature (100%) rename tests/{ => bdd}/features/tag.feature (100%) rename tests/{ => bdd}/features/upgrade.feature (100%) rename tests/{ => bdd}/features/write.feature (100%) create mode 100644 tests/bdd/test_features.py rename tests/{step_defs => }/conftest.py (81%) delete mode 100644 tests/step_defs/__init__.py delete mode 100644 tests/step_defs/fixtures.py delete mode 100644 tests/step_defs/given_steps.py delete mode 100644 tests/step_defs/helpers.py delete mode 100644 tests/step_defs/test_features.py delete mode 100644 tests/step_defs/then_steps.py delete mode 100644 tests/step_defs/when_steps.py diff --git a/Makefile b/Makefile index a04a9c86..a4494ee3 100644 --- a/Makefile +++ b/Makefile @@ -24,13 +24,13 @@ lint: ## Check style with various tools unit: # unit tests poetry run pytest tests/unit -e2e: # end-to-end tests - poetry run pytest tests/step_defs --gherkin-terminal-reporter --tb=native --diff-type=unified +bdd: # bdd tests + poetry run pytest tests/bdd --gherkin-terminal-reporter --tb=native --diff-type=unified -e2e-debug: # end-to-end tests - poetry run pytest tests/step_defs --gherkin-terminal-reporter --tb=native --diff-type=unified -x -vv +bdd-debug: # bdd tests + poetry run pytest tests/bdd --gherkin-terminal-reporter --tb=native --diff-type=unified -x -vv -test: lint unit e2e ## Run unit tests and behave tests +test: lint unit bdd ## Run unit tests and behave tests build: poetry build diff --git a/poetry.lock b/poetry.lock index 50b41e3c..2d1a8ea2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -214,7 +214,7 @@ python-versions = "*" [[package]] name = "importlib-metadata" -version = "4.5.0" +version = "4.6.0" description = "Read metadata from Python packages" category = "main" optional = false @@ -226,7 +226,8 @@ zipp = ">=0.5" [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +perf = ["ipython"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" @@ -444,11 +445,11 @@ python-versions = "*" [[package]] name = "packaging" -version = "20.9" +version = "21.0" description = "Core utilities for Python packages" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.dependencies] pyparsing = ">=2.0.2" @@ -641,11 +642,11 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xm [[package]] name = "pytest-bdd" -version = "4.0.2" +version = "4.1.0" description = "BDD for pytest" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" [package.dependencies] glob2 = "*" @@ -654,7 +655,6 @@ parse = "*" parse-type = "*" py = "*" pytest = ">=4.3" -six = ">=1.9.0" [[package]] name = "pytest-clarity" @@ -724,7 +724,7 @@ pyyaml = "*" [[package]] name = "regex" -version = "2021.4.4" +version = "2021.7.1" description = "Alternative regular expression module, to replace re." category = "dev" optional = false @@ -861,7 +861,7 @@ test = ["coverage", "flake8", "wheel"] [[package]] name = "zipp" -version = "3.4.1" +version = "3.5.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false @@ -869,7 +869,7 @@ python-versions = ">=3.6" [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] [metadata] lock-version = "1.1" @@ -992,8 +992,8 @@ glob2 = [ {file = "glob2-0.7.tar.gz", hash = "sha256:85c3dbd07c8aa26d63d7aacee34fa86e9a91a3873bc30bf62ec46e531f92ab8c"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.5.0-py3-none-any.whl", hash = "sha256:833b26fb89d5de469b24a390e9df088d4e52e4ba33b01dc5e0e4f41b81a16c00"}, - {file = "importlib_metadata-4.5.0.tar.gz", hash = "sha256:b142cc1dd1342f31ff04bb7d022492b09920cb64fed867cd3ea6f80fe3ebd139"}, + {file = "importlib_metadata-4.6.0-py3-none-any.whl", hash = "sha256:c6513572926a96458f8c8f725bf0e00108fba0c9583ade9bd15b869c9d726e33"}, + {file = "importlib_metadata-4.6.0.tar.gz", hash = "sha256:4a5611fea3768d3d967c447ab4e93f567d95db92225b43b7b238dbfb855d70bb"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -1090,8 +1090,8 @@ mypy-extensions = [ {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] packaging = [ - {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"}, - {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"}, + {file = "packaging-21.0-py3-none-any.whl", hash = "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14"}, + {file = "packaging-21.0.tar.gz", hash = "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7"}, ] parse = [ {file = "parse-1.19.0.tar.gz", hash = "sha256:9ff82852bcb65d139813e2a5197627a94966245c897796760a3a2a8eb66f020b"}, @@ -1165,8 +1165,8 @@ pytest = [ {file = "pytest-6.2.4.tar.gz", hash = "sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b"}, ] pytest-bdd = [ - {file = "pytest-bdd-4.0.2.tar.gz", hash = "sha256:982489f2f036c7561affe4eeb5b392a37e1ace2a9f260cad747b1c8119e63cfd"}, - {file = "pytest_bdd-4.0.2-py2.py3-none-any.whl", hash = "sha256:74ea5a147ea558c99ae83d838e6acbe5c9e6843884a958f8231615d96838733d"}, + {file = "pytest-bdd-4.1.0.tar.gz", hash = "sha256:304cd2b09923b838d0c2f08331d1f4236a14ef3594efa94e3bdae0f384d3fa5d"}, + {file = "pytest_bdd-4.1.0-py3-none-any.whl", hash = "sha256:7c5221680cec9a97630e1fae6132f4a97c2f86a90914206ee06a55ae1a409fe5"}, ] pytest-clarity = [ {file = "pytest-clarity-0.3.0a0.tar.gz", hash = "sha256:5cc99e3d9b7969dfe17e5f6072d45a917c59d363b679686d3c958a1ded2e4dcf"}, @@ -1215,47 +1215,43 @@ pyyaml-env-tag = [ {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, ] regex = [ - {file = "regex-2021.4.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:619d71c59a78b84d7f18891fe914446d07edd48dc8328c8e149cbe0929b4e000"}, - {file = "regex-2021.4.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:47bf5bf60cf04d72bf6055ae5927a0bd9016096bf3d742fa50d9bf9f45aa0711"}, - {file = "regex-2021.4.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:281d2fd05555079448537fe108d79eb031b403dac622621c78944c235f3fcf11"}, - {file = "regex-2021.4.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:bd28bc2e3a772acbb07787c6308e00d9626ff89e3bfcdebe87fa5afbfdedf968"}, - {file = "regex-2021.4.4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:7c2a1af393fcc09e898beba5dd59196edaa3116191cc7257f9224beaed3e1aa0"}, - {file = "regex-2021.4.4-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c38c71df845e2aabb7fb0b920d11a1b5ac8526005e533a8920aea97efb8ec6a4"}, - {file = "regex-2021.4.4-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:96fcd1888ab4d03adfc9303a7b3c0bd78c5412b2bfbe76db5b56d9eae004907a"}, - {file = "regex-2021.4.4-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:ade17eb5d643b7fead300a1641e9f45401c98eee23763e9ed66a43f92f20b4a7"}, - {file = "regex-2021.4.4-cp36-cp36m-win32.whl", hash = "sha256:e8e5b509d5c2ff12f8418006d5a90e9436766133b564db0abaec92fd27fcee29"}, - {file = "regex-2021.4.4-cp36-cp36m-win_amd64.whl", hash = "sha256:11d773d75fa650cd36f68d7ca936e3c7afaae41b863b8c387a22aaa78d3c5c79"}, - {file = "regex-2021.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d3029c340cfbb3ac0a71798100ccc13b97dddf373a4ae56b6a72cf70dfd53bc8"}, - {file = "regex-2021.4.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:18c071c3eb09c30a264879f0d310d37fe5d3a3111662438889ae2eb6fc570c31"}, - {file = "regex-2021.4.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:4c557a7b470908b1712fe27fb1ef20772b78079808c87d20a90d051660b1d69a"}, - {file = "regex-2021.4.4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:01afaf2ec48e196ba91b37451aa353cb7eda77efe518e481707e0515025f0cd5"}, - {file = "regex-2021.4.4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:3a9cd17e6e5c7eb328517969e0cb0c3d31fd329298dd0c04af99ebf42e904f82"}, - {file = "regex-2021.4.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:90f11ff637fe8798933fb29f5ae1148c978cccb0452005bf4c69e13db951e765"}, - {file = "regex-2021.4.4-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:919859aa909429fb5aa9cf8807f6045592c85ef56fdd30a9a3747e513db2536e"}, - {file = "regex-2021.4.4-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:339456e7d8c06dd36a22e451d58ef72cef293112b559010db3d054d5560ef439"}, - {file = "regex-2021.4.4-cp37-cp37m-win32.whl", hash = "sha256:67bdb9702427ceddc6ef3dc382455e90f785af4c13d495f9626861763ee13f9d"}, - {file = "regex-2021.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:32e65442138b7b76dd8173ffa2cf67356b7bc1768851dded39a7a13bf9223da3"}, - {file = "regex-2021.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1e1c20e29358165242928c2de1482fb2cf4ea54a6a6dea2bd7a0e0d8ee321500"}, - {file = "regex-2021.4.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:314d66636c494ed9c148a42731b3834496cc9a2c4251b1661e40936814542b14"}, - {file = "regex-2021.4.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6d1b01031dedf2503631d0903cb563743f397ccaf6607a5e3b19a3d76fc10480"}, - {file = "regex-2021.4.4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:741a9647fcf2e45f3a1cf0e24f5e17febf3efe8d4ba1281dcc3aa0459ef424dc"}, - {file = "regex-2021.4.4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4c46e22a0933dd783467cf32b3516299fb98cfebd895817d685130cc50cd1093"}, - {file = "regex-2021.4.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:e512d8ef5ad7b898cdb2d8ee1cb09a8339e4f8be706d27eaa180c2f177248a10"}, - {file = "regex-2021.4.4-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:980d7be47c84979d9136328d882f67ec5e50008681d94ecc8afa8a65ed1f4a6f"}, - {file = "regex-2021.4.4-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:ce15b6d103daff8e9fee13cf7f0add05245a05d866e73926c358e871221eae87"}, - {file = "regex-2021.4.4-cp38-cp38-win32.whl", hash = "sha256:a91aa8619b23b79bcbeb37abe286f2f408d2f2d6f29a17237afda55bb54e7aac"}, - {file = "regex-2021.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:c0502c0fadef0d23b128605d69b58edb2c681c25d44574fc673b0e52dce71ee2"}, - {file = "regex-2021.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:598585c9f0af8374c28edd609eb291b5726d7cbce16be6a8b95aa074d252ee17"}, - {file = "regex-2021.4.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:ee54ff27bf0afaf4c3b3a62bcd016c12c3fdb4ec4f413391a90bd38bc3624605"}, - {file = "regex-2021.4.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7d9884d86dd4dd489e981d94a65cd30d6f07203d90e98f6f657f05170f6324c9"}, - {file = "regex-2021.4.4-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:bf5824bfac591ddb2c1f0a5f4ab72da28994548c708d2191e3b87dd207eb3ad7"}, - {file = "regex-2021.4.4-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:563085e55b0d4fb8f746f6a335893bda5c2cef43b2f0258fe1020ab1dd874df8"}, - {file = "regex-2021.4.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9c3db21af35e3b3c05764461b262d6f05bbca08a71a7849fd79d47ba7bc33ed"}, - {file = "regex-2021.4.4-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:3916d08be28a1149fb97f7728fca1f7c15d309a9f9682d89d79db75d5e52091c"}, - {file = "regex-2021.4.4-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:fd45ff9293d9274c5008a2054ecef86a9bfe819a67c7be1afb65e69b405b3042"}, - {file = "regex-2021.4.4-cp39-cp39-win32.whl", hash = "sha256:fa4537fb4a98fe8fde99626e4681cc644bdcf2a795038533f9f711513a862ae6"}, - {file = "regex-2021.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:97f29f57d5b84e73fbaf99ab3e26134e6687348e95ef6b48cfd2c06807005a07"}, - {file = "regex-2021.4.4.tar.gz", hash = "sha256:52ba3d3f9b942c49d7e4bc105bb28551c44065f139a65062ab7912bef10c9afb"}, + {file = "regex-2021.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:494d0172774dc0beeea984b94c95389143db029575f7ca908edd74469321ea99"}, + {file = "regex-2021.7.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:8cf6728f89b071bd3ab37cb8a0e306f4de897553a0ed07442015ee65fbf53d62"}, + {file = "regex-2021.7.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1806370b2bef4d4193eebe8ee59a9fd7547836a34917b7badbe6561a8594d9cb"}, + {file = "regex-2021.7.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d0cf2651a8804f6325747c7e55e3be0f90ee2848e25d6b817aa2728d263f9abb"}, + {file = "regex-2021.7.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:268fe9dd1deb4a30c8593cabd63f7a241dfdc5bd9dd0233906c718db22cdd49a"}, + {file = "regex-2021.7.1-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:7743798dfb573d006f1143d745bf17efad39775a5190b347da5d83079646be56"}, + {file = "regex-2021.7.1-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:0e46c1191b2eb293a6912269ed08b4512e7e241bbf591f97e527492e04c77e93"}, + {file = "regex-2021.7.1-cp36-cp36m-win32.whl", hash = "sha256:b1dbeef938281f240347d50f28ae53c4b046a23389cd1fc4acec5ea0eae646a1"}, + {file = "regex-2021.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:6c72ebb72e64e9bd195cb35a9b9bbfb955fd953b295255b8ae3e4ad4a146b615"}, + {file = "regex-2021.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bf819c5b77ff44accc9a24e31f1f7ceaaf6c960816913ed3ef8443b9d20d81b6"}, + {file = "regex-2021.7.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:e80d2851109e56420b71f9702ad1646e2f0364528adbf6af85527bc61e49f394"}, + {file = "regex-2021.7.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a1b6a3f600d6aff97e3f28c34192c9ed93fee293bd96ef327b64adb51a74b2f6"}, + {file = "regex-2021.7.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:ed77b97896312bc2deafe137ca2626e8b63808f5bedb944f73665c68093688a7"}, + {file = "regex-2021.7.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:a548bb51c4476332ce4139df8e637386730f79a92652a907d12c696b6252b64d"}, + {file = "regex-2021.7.1-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:210c359e6ee5b83f7d8c529ba3c75ba405481d50f35a420609b0db827e2e3bb5"}, + {file = "regex-2021.7.1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:1d386402ae7f3c9b107ae5863f7ecccb0167762c82a687ae6526b040feaa5ac6"}, + {file = "regex-2021.7.1-cp37-cp37m-win32.whl", hash = "sha256:5049d00dbb78f9d166d1c704e93934d42cce0570842bb1a61695123d6b01de09"}, + {file = "regex-2021.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:361be4d311ac995a8c7ad577025a3ae3a538531b1f2cf32efd8b7e5d33a13e5a"}, + {file = "regex-2021.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f32f47fb22c988c0b35756024b61d156e5c4011cb8004aa53d93b03323c45657"}, + {file = "regex-2021.7.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:b024ee43ee6b310fad5acaee23e6485b21468718cb792a9d1693eecacc3f0b7e"}, + {file = "regex-2021.7.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:b092754c06852e8a8b022004aff56c24b06310189186805800d09313c37ce1f8"}, + {file = "regex-2021.7.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:a8a5826d8a1b64e2ff9af488cc179e1a4d0f144d11ce486a9f34ea38ccedf4ef"}, + {file = "regex-2021.7.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:444723ebaeb7fa8125f29c01a31101a3854ac3de293e317944022ae5effa53a4"}, + {file = "regex-2021.7.1-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:fdad3122b69cdabdb3da4c2a4107875913ac78dab0117fc73f988ad589c66b66"}, + {file = "regex-2021.7.1-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:4b1999ef60c45357598935c12508abf56edbbb9c380df6f336de38a6c3a294ae"}, + {file = "regex-2021.7.1-cp38-cp38-win32.whl", hash = "sha256:e07e92935040c67f49571779d115ecb3e727016d42fb36ee0d8757db4ca12ee0"}, + {file = "regex-2021.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:6b8b629f93246e507287ee07e26744beaffb4c56ed520576deac8b615bd76012"}, + {file = "regex-2021.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:56bef6b414949e2c9acf96cb5d78de8b529c7b99752619494e78dc76f99fd005"}, + {file = "regex-2021.7.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:78a2a885345a2d60b5e68099e877757d5ed12e46ba1e87507175f14f80892af3"}, + {file = "regex-2021.7.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:3f7a92e60930f8fca2623d9e326c173b7cf2c8b7e4fdcf984b75a1d2fb08114d"}, + {file = "regex-2021.7.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4fc86b729ab88fe8ac3ec92287df253c64aa71560d76da5acd8a2e245839c629"}, + {file = "regex-2021.7.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:59845101de68fd5d3a1145df9ea022e85ecd1b49300ea68307ad4302320f6f61"}, + {file = "regex-2021.7.1-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:ce269e903b00d1ab4746793e9c50a57eec5d5388681abef074d7b9a65748fca5"}, + {file = "regex-2021.7.1-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:c11f2fca544b5e30a0e813023196a63b1cb9869106ef9a26e9dae28bce3e4e26"}, + {file = "regex-2021.7.1-cp39-cp39-win32.whl", hash = "sha256:1ccbd41dbee3a31e18938096510b7d4ee53aa9fce2ee3dcc8ec82ae264f6acfd"}, + {file = "regex-2021.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:18040755606b0c21281493ec309214bd61e41a170509e5014f41d6a5a586e161"}, + {file = "regex-2021.7.1.tar.gz", hash = "sha256:849802379a660206277675aa5a5c327f5c910c690649535863ddf329b0ba8c87"}, ] secretstorage = [ {file = "SecretStorage-3.3.1-py3-none-any.whl", hash = "sha256:422d82c36172d88d6a0ed5afdec956514b189ddbfb72fefab0c8a1cee4eaf71f"}, @@ -1357,6 +1353,6 @@ yq = [ {file = "yq-2.12.2.tar.gz", hash = "sha256:2f156d0724b61487ac8752ed4eaa702a5737b804d5afa46fa55866951cd106d2"}, ] zipp = [ - {file = "zipp-3.4.1-py3-none-any.whl", hash = "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098"}, - {file = "zipp-3.4.1.tar.gz", hash = "sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76"}, + {file = "zipp-3.5.0-py3-none-any.whl", hash = "sha256:957cfda87797e389580cb8b9e3870841ca991e2125350677b2ca83a0e99390a3"}, + {file = "zipp-3.5.0.tar.gz", hash = "sha256:f5812b1e007e48cff63449a5e9f4e7ebea716b4111f9c4f9a645f91d579bf0c4"}, ] diff --git a/tests/features/build.feature b/tests/bdd/features/build.feature similarity index 100% rename from tests/features/build.feature rename to tests/bdd/features/build.feature diff --git a/tests/features/core.feature b/tests/bdd/features/core.feature similarity index 100% rename from tests/features/core.feature rename to tests/bdd/features/core.feature diff --git a/tests/features/datetime.feature b/tests/bdd/features/datetime.feature similarity index 100% rename from tests/features/datetime.feature rename to tests/bdd/features/datetime.feature diff --git a/tests/features/delete.feature b/tests/bdd/features/delete.feature similarity index 100% rename from tests/features/delete.feature rename to tests/bdd/features/delete.feature diff --git a/tests/features/encrypt.feature b/tests/bdd/features/encrypt.feature similarity index 100% rename from tests/features/encrypt.feature rename to tests/bdd/features/encrypt.feature diff --git a/tests/features/file_storage.feature b/tests/bdd/features/file_storage.feature similarity index 100% rename from tests/features/file_storage.feature rename to tests/bdd/features/file_storage.feature diff --git a/tests/features/format.feature b/tests/bdd/features/format.feature similarity index 100% rename from tests/features/format.feature rename to tests/bdd/features/format.feature diff --git a/tests/features/import.feature b/tests/bdd/features/import.feature similarity index 100% rename from tests/features/import.feature rename to tests/bdd/features/import.feature diff --git a/tests/features/multiple_journals.feature b/tests/bdd/features/multiple_journals.feature similarity index 100% rename from tests/features/multiple_journals.feature rename to tests/bdd/features/multiple_journals.feature diff --git a/tests/features/password.feature b/tests/bdd/features/password.feature similarity index 100% rename from tests/features/password.feature rename to tests/bdd/features/password.feature diff --git a/tests/features/search.feature b/tests/bdd/features/search.feature similarity index 100% rename from tests/features/search.feature rename to tests/bdd/features/search.feature diff --git a/tests/features/star.feature b/tests/bdd/features/star.feature similarity index 100% rename from tests/features/star.feature rename to tests/bdd/features/star.feature diff --git a/tests/features/tag.feature b/tests/bdd/features/tag.feature similarity index 100% rename from tests/features/tag.feature rename to tests/bdd/features/tag.feature diff --git a/tests/features/upgrade.feature b/tests/bdd/features/upgrade.feature similarity index 100% rename from tests/features/upgrade.feature rename to tests/bdd/features/upgrade.feature diff --git a/tests/features/write.feature b/tests/bdd/features/write.feature similarity index 100% rename from tests/features/write.feature rename to tests/bdd/features/write.feature diff --git a/tests/bdd/test_features.py b/tests/bdd/test_features.py new file mode 100644 index 00000000..b824df39 --- /dev/null +++ b/tests/bdd/test_features.py @@ -0,0 +1,17 @@ +from pytest_bdd import scenarios + +scenarios("features/build.feature") +scenarios("features/core.feature") +scenarios("features/datetime.feature") +scenarios("features/delete.feature") +scenarios("features/encrypt.feature") +scenarios("features/file_storage.feature") +scenarios("features/format.feature") +scenarios("features/import.feature") +scenarios("features/multiple_journals.feature") +scenarios("features/password.feature") +scenarios("features/search.feature") +scenarios("features/star.feature") +scenarios("features/tag.feature") +scenarios("features/upgrade.feature") +scenarios("features/write.feature") diff --git a/tests/step_defs/conftest.py b/tests/conftest.py similarity index 81% rename from tests/step_defs/conftest.py rename to tests/conftest.py index a3021972..277e2602 100644 --- a/tests/step_defs/conftest.py +++ b/tests/conftest.py @@ -7,10 +7,10 @@ from jrnl.os_compat import on_windows pytest_plugins = [ - "tests.step_defs.fixtures", - "tests.step_defs.given_steps", - "tests.step_defs.when_steps", - "tests.step_defs.then_steps", + "tests.lib.fixtures", + "tests.lib.given_steps", + "tests.lib.when_steps", + "tests.lib.then_steps", ] diff --git a/tests/step_defs/__init__.py b/tests/step_defs/__init__.py deleted file mode 100644 index 46468510..00000000 --- a/tests/step_defs/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -import sys - -sys.path.append("..") diff --git a/tests/step_defs/fixtures.py b/tests/step_defs/fixtures.py deleted file mode 100644 index a93a7e43..00000000 --- a/tests/step_defs/fixtures.py +++ /dev/null @@ -1,201 +0,0 @@ -# Copyright (C) 2012-2021 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 keyring import backend -from keyring import errors -from keyring import set_keyring -from pytest import fixture -import toml - -from jrnl.config import load_config - - -# --- Keyring --- # -@fixture -def keyring(): - set_keyring(NoKeyring()) - - -@fixture -def keyring_type(): - return "default" - - -class TestKeyring(backend.KeyringBackend): - """A test keyring that just stores its values in a hash""" - - priority = 1 - keys = defaultdict(dict) - - def set_password(self, servicename, username, password): - self.keys[servicename][username] = password - - def get_password(self, servicename, username): - return self.keys[servicename].get(username) - - def delete_password(self, servicename, username): - self.keys[servicename][username] = None - - -class NoKeyring(backend.KeyringBackend): - """A keyring that simulated an environment with no keyring backend.""" - - priority = 2 - keys = defaultdict(dict) - - def set_password(self, servicename, username, password): - raise errors.NoKeyringError - - def get_password(self, servicename, username): - raise errors.NoKeyringError - - def delete_password(self, servicename, username): - raise errors.NoKeyringError - - -class FailedKeyring(backend.KeyringBackend): - """A keyring that cannot be retrieved.""" - - priority = 2 - - def set_password(self, servicename, username, password): - raise errors.KeyringError - - def get_password(self, servicename, username): - raise errors.KeyringError - - def delete_password(self, servicename, username): - raise errors.KeyringError - - -# ----- Misc ----- # -@fixture -def cli_run(): - return {"status": 0, "stdout": None, "stderr": None} - - -@fixture -def mocks(): - return dict() - - -@fixture -def temp_dir(): - return tempfile.TemporaryDirectory() - - -@fixture -def working_dir(request): - return os.path.join(request.config.rootpath, "tests") - - -@fixture -def config_path(temp_dir): - os.chdir(temp_dir.name) - return temp_dir.name + "/jrnl.yaml" - - -@fixture -def toml_version(working_dir): - pyproject = os.path.join(working_dir, "..", "pyproject.toml") - pyproject_contents = toml.load(pyproject) - return pyproject_contents["tool"]["poetry"]["version"] - - -@fixture -def password(): - return "" - - -@fixture -def input_method(): - return "" - - -@fixture -def cache_dir(): - return {"exists": False, "path": ""} - - -@fixture -def str_value(): - return "" - - -@fixture -def command(): - return "" - - -@fixture -def should_not(): - return False - - -@fixture -def user_input(): - return "" - - -@fixture -def config_data(config_path): - return load_config(config_path) - - -@fixture -def journal_name(): - return None - - -@fixture -def which_output_stream(): - return None - - -@fixture -def editor_input(): - return None - - -@fixture -def num_args(): - return None - - -@fixture -def parsed_output(): - return {"lang": None, "obj": None} - - -@fixture -def editor_state(): - return { - "command": "", - "intent": {"method": "r", "input": None}, - "tmpfile": {"name": None, "content": None}, - } - - -@fixture -def editor(editor_state): - def _mock_editor(editor_command): - tmpfile = editor_command[-1] - - editor_state["command"] = editor_command - editor_state["tmpfile"]["name"] = tmpfile - - Path(tmpfile).touch() - with open(tmpfile, editor_state["intent"]["method"]) as f: - # Touch the file so jrnl knows it was edited - if editor_state["intent"]["input"] is not None: - f.write(editor_state["intent"]["input"]) - - file_content = f.read() - editor_state["tmpfile"]["content"] = file_content - - return _mock_editor diff --git a/tests/step_defs/given_steps.py b/tests/step_defs/given_steps.py deleted file mode 100644 index 649d44c5..00000000 --- a/tests/step_defs/given_steps.py +++ /dev/null @@ -1,134 +0,0 @@ -# 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 ""')) -@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 ""', 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('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} diff --git a/tests/step_defs/helpers.py b/tests/step_defs/helpers.py deleted file mode 100644 index 7d089597..00000000 --- a/tests/step_defs/helpers.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (C) 2012-2021 jrnl contributors -# License: https://www.gnu.org/licenses/gpl-3.0.html - -import os - - -def does_directory_contain_files(file_list, directory_path): - if not os.path.isdir(directory_path): - return False - - for file in file_list.split("\n"): - fullpath = directory_path + "/" + file - if not os.path.isfile(fullpath): - return False - - return True - - -def parse_should_or_should_not(should_or_should_not): - if should_or_should_not == "should": - return True - elif should_or_should_not == "should not": - return False - else: - raise Exception( - "should_or_should_not valid values are 'should' or 'should not'" - ) - - -def assert_equal_tags_ignoring_order( - actual_line, expected_line, actual_content, expected_content -): - actual_tags = set(tag.strip() for tag in actual_line[len("tags: ") :].split(",")) - expected_tags = set( - tag.strip() for tag in expected_line[len("tags: ") :].split(",") - ) - assert actual_tags == expected_tags, [ - [actual_tags, expected_tags], - [expected_content, actual_content], - ] diff --git a/tests/step_defs/test_features.py b/tests/step_defs/test_features.py deleted file mode 100644 index 4c8d5ef9..00000000 --- a/tests/step_defs/test_features.py +++ /dev/null @@ -1,17 +0,0 @@ -from pytest_bdd import scenarios - -scenarios("../features/build.feature") -scenarios("../features/core.feature") -scenarios("../features/datetime.feature") -scenarios("../features/delete.feature") -scenarios("../features/encrypt.feature") -scenarios("../features/file_storage.feature") -scenarios("../features/format.feature") -scenarios("../features/import.feature") -scenarios("../features/multiple_journals.feature") -scenarios("../features/password.feature") -scenarios("../features/search.feature") -scenarios("../features/star.feature") -scenarios("../features/tag.feature") -scenarios("../features/upgrade.feature") -scenarios("../features/write.feature") diff --git a/tests/step_defs/then_steps.py b/tests/step_defs/then_steps.py deleted file mode 100644 index b56c203f..00000000 --- a/tests/step_defs/then_steps.py +++ /dev/null @@ -1,331 +0,0 @@ -# Copyright (C) 2012-2021 jrnl contributors -# License: https://www.gnu.org/licenses/gpl-3.0.html - -import json -import os -import re -from xml.etree import ElementTree - -from pytest_bdd import then -from pytest_bdd.parsers import parse -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 - - -@then("we should get no error") -def should_get_no_error(cli_run): - assert cli_run["status"] == 0, cli_run["status"] - - -@then(parse('the output should match "{regex}"')) -def output_should_match(regex, cli_run): - out = cli_run["stdout"] - matches = re.findall(regex, out) - assert matches, f"\nRegex didn't match:\n{regex}\n{str(out)}\n{str(matches)}" - - -@then(parse("the output should contain\n{expected_output}")) -@then(parse('the output should contain "{expected_output}"')) -@then('the output should contain ""') -@then(parse("the {which_output_stream} output should contain\n{expected_output}")) -@then(parse('the {which_output_stream} output should contain "{expected_output}"')) -def output_should_contain(expected_output, which_output_stream, cli_run): - assert expected_output - if which_output_stream is None: - assert (expected_output in cli_run["stdout"]) or ( - expected_output in cli_run["stderr"] - ) - - elif which_output_stream == "standard": - assert expected_output in cli_run["stdout"] - - elif which_output_stream == "error": - assert expected_output in cli_run["stderr"] - - else: - assert expected_output in cli_run[which_output_stream] - - -@then(parse("the output should not contain\n{expected_output}")) -@then(parse('the output should not contain "{expected_output}"')) -@then('the output should not contain ""') -def output_should_not_contain(expected_output, cli_run): - assert expected_output not in cli_run["stdout"] - - -@then(parse("the output should be\n{expected_output}")) -@then(parse('the output should be "{expected_output}"')) -@then('the output should be ""') -def output_should_be(expected_output, cli_run): - actual = cli_run["stdout"].strip() - expected = expected_output.strip() - assert expected == actual - - -@then("the output should be empty") -def output_should_be_empty(cli_run): - actual = cli_run["stdout"].strip() - assert actual == "" - - -@then('the output should contain the date ""') -def output_should_contain_date(date, cli_run): - assert date and date in cli_run["stdout"] - - -@then("the output should contain pyproject.toml version") -def output_should_contain_version(cli_run, toml_version): - out = cli_run["stdout"] - assert toml_version in out, toml_version - - -@then(parse('we should see the message "{text}"')) -def should_see_the_message(text, cli_run): - out = cli_run["stderr"] - assert text in out, [text, out] - - -@then( - parse( - 'the config for journal "{journal_name}" {should_or_should_not} contain "{some_yaml}"' - ) -) -@then( - parse( - 'the config for journal "{journal_name}" {should_or_should_not} contain\n{some_yaml}' - ) -) -@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): - we_should = parse_should_or_should_not(should_or_should_not) - - actual = config_data - if journal_name: - actual = actual["journals"][journal_name] - - expected = yaml.load(some_yaml, Loader=yaml.FullLoader) - - actual_slice = actual - if type(actual) is dict: - actual_slice = {key: actual.get(key, None) 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 - - -@then("we should not be prompted for a password") -def password_was_not_called(cli_run): - assert not cli_run["mocks"]["getpass"].called - - -@then(parse("the cache directory should contain the files\n{file_list}")) -def assert_dir_contains_files(file_list, cache_dir): - assert does_directory_contain_files(file_list, cache_dir["path"]) - - -@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") - - 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) - - assert not does_directory_contain_files( - scoped_config["journal"], "." - ), f'Journal "{journal_name}" does exist' - - -@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") - expected_path = scoped_config["journal"] - - contains_files = does_directory_contain_files(expected_path, ".") - - if should_or_should_not == "should": - assert contains_files - elif should_or_should_not == "should not": - assert not contains_files - else: - raise Exception( - "should_or_should_not valid values are 'should' or 'should not'" - ) - - -@then(parse('the content of file "{file_path}" in the cache should be\n{file_content}')) -def content_of_file_should_be(file_path, file_content, cache_dir): - assert cache_dir["exists"] - expected_content = file_content.strip().splitlines() - - with open(os.path.join(cache_dir["path"], file_path), "r") as f: - actual_content = f.read().strip().splitlines() - - for actual_line, expected_line in zip(actual_content, expected_content): - if actual_line.startswith("tags: ") and expected_line.startswith("tags: "): - assert_equal_tags_ignoring_order( - actual_line, expected_line, actual_content, expected_content - ) - else: - assert actual_line.strip() == expected_line.strip(), [ - [actual_line.strip(), expected_line.strip()], - [actual_content, expected_content], - ] - - -@then(parse("the cache should contain the files\n{file_list}")) -def cache_dir_contains_files(file_list, cache_dir): - assert cache_dir["exists"] - - actual_files = os.listdir(cache_dir["path"]) - expected_files = file_list.split("\n") - - # sort to deal with inconsistent default file ordering on different OS's - actual_files.sort() - expected_files.sort() - - assert actual_files == expected_files, [actual_files, expected_files] - - -@then(parse("the output should be valid {language_name}")) -def assert_output_is_valid_language(cli_run, language_name): - language_name = language_name.upper() - if language_name == "XML": - xml_tree = ElementTree.fromstring(cli_run["stdout"]) - assert xml_tree, "Invalid XML" - elif language_name == "JSON": - assert json.loads(cli_run["stdout"]), "Invalid JSON" - else: - assert False, f"Language name {language_name} not recognized" - - -@then(parse('"{node_name}" in the parsed output should have {number:d} elements')) -def assert_parsed_output_item_count(node_name, number, parsed_output): - lang = parsed_output["lang"] - obj = parsed_output["obj"] - - if lang == "XML": - xml_node_names = (node.tag for node in obj) - assert node_name in xml_node_names, str(list(xml_node_names)) - - actual_entry_count = len(obj.find(node_name)) - assert actual_entry_count == number, actual_entry_count - - elif lang == "JSON": - my_obj = obj - - for node in node_name.split("."): - try: - my_obj = my_obj[int(node)] - except ValueError: - assert node in my_obj - my_obj = my_obj[node] - - assert len(my_obj) == number, len(my_obj) - - else: - assert False, f"Language name {lang} not recognized" - - -@then(parse('"{field_name}" in the parsed output should {comparison}\n{expected_keys}')) -def assert_output_field_content(field_name, comparison, expected_keys, parsed_output): - lang = parsed_output["lang"] - obj = parsed_output["obj"] - expected_keys = expected_keys.split("\n") - if len(expected_keys) == 1: - expected_keys = expected_keys[0] - - if lang == "XML": - xml_node_names = (node.tag for node in obj) - assert field_name in xml_node_names, str(list(xml_node_names)) - - if field_name == "tags": - actual_tags = set(t.attrib["name"] for t in obj.find("tags")) - assert set(actual_tags) == set(expected_keys), [ - actual_tags, - set(expected_keys), - ] - else: - assert False, "This test only works for tags in XML" - - elif lang == "JSON": - my_obj = obj - - for node in field_name.split("."): - try: - my_obj = my_obj[int(node)] - except ValueError: - assert node in my_obj, [my_obj.keys(), node] - my_obj = my_obj[node] - - if comparison == "be": - if type(my_obj) is str: - assert expected_keys == my_obj, [my_obj, expected_keys] - else: - assert set(expected_keys) == set(my_obj), [ - set(my_obj), - set(expected_keys), - ] - elif comparison == "contain": - if type(my_obj) is str: - assert expected_keys in my_obj, [my_obj, expected_keys] - else: - assert all(elem in my_obj for elem in expected_keys), [ - my_obj, - expected_keys, - ] - else: - assert False, f"Language name {lang} not recognized" - - -@then(parse('there should be {number:d} "{item}" elements')) -def count_elements(number, item, cli_run): - actual_output = cli_run["stdout"] - xml_tree = ElementTree.fromstring(actual_output) - 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 - - if isinstance(num_args, int): - assert len(editor_state["command"]) == int(num_args) - - -@then(parse('the editor filename should end with "{suffix}"')) -def editor_filename_suffix(suffix, editor_state): - editor_filename = editor_state["tmpfile"]["name"] - - assert editor_state["tmpfile"]["name"].endswith(suffix), (editor_filename, suffix) - - -@then(parse('the editor file content should {comparison} "{str_value}"')) -@then(parse("the editor file content should {comparison} empty")) -@then(parse("the editor file content should {comparison}\n{str_value}")) -def contains_editor_file(comparison, str_value, editor_state): - content = editor_state["tmpfile"]["content"] - # content = f'\n"""\n{content}\n"""\n' - if comparison == "be": - assert content == str_value - elif comparison == "contain": - assert str_value in content - else: - assert False, f"Comparison '{comparison}' not supported" diff --git a/tests/step_defs/when_steps.py b/tests/step_defs/when_steps.py deleted file mode 100644 index 2e72173b..00000000 --- a/tests/step_defs/when_steps.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright (C) 2012-2021 jrnl contributors -# License: https://www.gnu.org/licenses/gpl-3.0.html - -from contextlib import ExitStack -import os -from unittest.mock import patch - -from pytest_bdd import parsers -from pytest_bdd import when -from pytest_bdd.parsers import parse - -from jrnl.cli import cli -from jrnl.os_compat import split_args - - -@when(parse('we change directory to "{directory_name}"')) -def when_we_change_directory(directory_name): - if not os.path.isdir(directory_name): - os.mkdir(directory_name) - - os.chdir(directory_name) - - -@when(parse('we run "jrnl {command}" and {input_method}\n{user_input}')) -@when( - parsers.re( - 'we run "jrnl (?P[^"]+)" and (?Penter|pipe) "(?P[^"]+)"' - ) -) -@when(parse('we run "jrnl" and {input_method} "{user_input}"')) -@when(parse('we run "jrnl {command}"')) -@when('we run "jrnl "') -@when('we run "jrnl"') -def we_run( - command, - config_path, - user_input, - cli_run, - capsys, - password, - cache_dir, - editor, - keyring, - input_method, - mocks, -): - assert input_method in ["", "enter", "pipe"] - is_tty = input_method != "pipe" - - if cache_dir["exists"]: - command = command.format(cache_dir=cache_dir["path"]) - - args = split_args(command) - status = 0 - - if user_input: - user_input = user_input.splitlines() if is_tty else [user_input] - - if password: - password = password.splitlines() - - if not password and user_input: - password = user_input - - with ExitStack() as stack: - - stack.enter_context(patch("sys.argv", ["jrnl"] + args)) - - mock_stdin = stack.enter_context( - patch("sys.stdin.read", side_effect=user_input) - ) - stack.enter_context(patch("sys.stdin.isatty", return_value=is_tty)) - mock_input = stack.enter_context( - patch("builtins.input", side_effect=user_input) - ) - mock_getpass = stack.enter_context( - patch("getpass.getpass", side_effect=password) - ) - - if "datetime" in mocks: - stack.enter_context(mocks["datetime"]) - stack.enter_context(mocks["calendar_parse"]) - - # stack.enter_context(patch("datetime.datetime", new=mocks["datetime"])) - # stack.enter_context(patch("jrnl.time.__get_pdt_calendar", return_value=mocks["calendar_parse"])) - - stack.enter_context( - patch("jrnl.install.get_config_path", return_value=config_path) - ) - stack.enter_context( - patch("jrnl.config.get_config_path", return_value=config_path) - ) - mock_editor = stack.enter_context(patch("subprocess.call", side_effect=editor)) - - try: - cli(args) - except StopIteration: - # This happens when input is expected, but don't have any input left - pass - except SystemExit as e: - status = e.code - - captured = capsys.readouterr() - - cli_run["status"] = status - cli_run["stdout"] = captured.out - cli_run["stderr"] = captured.err - cli_run["mocks"] = { - "stdin": mock_stdin, - "input": mock_input, - "getpass": mock_getpass, - "editor": mock_editor, - } From d95dab9f0c7fa64c08e29118d84c6b0397a47550 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 3 Jul 2021 15:04:39 -0700 Subject: [PATCH 153/215] add actual lib directory even though it's in gitignore for some reason --- tests/lib/fixtures.py | 201 ++++++++++++++++++++++++ tests/lib/given_steps.py | 134 ++++++++++++++++ tests/lib/helpers.py | 40 +++++ tests/lib/then_steps.py | 331 +++++++++++++++++++++++++++++++++++++++ tests/lib/when_steps.py | 113 +++++++++++++ 5 files changed, 819 insertions(+) create mode 100644 tests/lib/fixtures.py create mode 100644 tests/lib/given_steps.py create mode 100644 tests/lib/helpers.py create mode 100644 tests/lib/then_steps.py create mode 100644 tests/lib/when_steps.py diff --git a/tests/lib/fixtures.py b/tests/lib/fixtures.py new file mode 100644 index 00000000..a93a7e43 --- /dev/null +++ b/tests/lib/fixtures.py @@ -0,0 +1,201 @@ +# Copyright (C) 2012-2021 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 keyring import backend +from keyring import errors +from keyring import set_keyring +from pytest import fixture +import toml + +from jrnl.config import load_config + + +# --- Keyring --- # +@fixture +def keyring(): + set_keyring(NoKeyring()) + + +@fixture +def keyring_type(): + return "default" + + +class TestKeyring(backend.KeyringBackend): + """A test keyring that just stores its values in a hash""" + + priority = 1 + keys = defaultdict(dict) + + def set_password(self, servicename, username, password): + self.keys[servicename][username] = password + + def get_password(self, servicename, username): + return self.keys[servicename].get(username) + + def delete_password(self, servicename, username): + self.keys[servicename][username] = None + + +class NoKeyring(backend.KeyringBackend): + """A keyring that simulated an environment with no keyring backend.""" + + priority = 2 + keys = defaultdict(dict) + + def set_password(self, servicename, username, password): + raise errors.NoKeyringError + + def get_password(self, servicename, username): + raise errors.NoKeyringError + + def delete_password(self, servicename, username): + raise errors.NoKeyringError + + +class FailedKeyring(backend.KeyringBackend): + """A keyring that cannot be retrieved.""" + + priority = 2 + + def set_password(self, servicename, username, password): + raise errors.KeyringError + + def get_password(self, servicename, username): + raise errors.KeyringError + + def delete_password(self, servicename, username): + raise errors.KeyringError + + +# ----- Misc ----- # +@fixture +def cli_run(): + return {"status": 0, "stdout": None, "stderr": None} + + +@fixture +def mocks(): + return dict() + + +@fixture +def temp_dir(): + return tempfile.TemporaryDirectory() + + +@fixture +def working_dir(request): + return os.path.join(request.config.rootpath, "tests") + + +@fixture +def config_path(temp_dir): + os.chdir(temp_dir.name) + return temp_dir.name + "/jrnl.yaml" + + +@fixture +def toml_version(working_dir): + pyproject = os.path.join(working_dir, "..", "pyproject.toml") + pyproject_contents = toml.load(pyproject) + return pyproject_contents["tool"]["poetry"]["version"] + + +@fixture +def password(): + return "" + + +@fixture +def input_method(): + return "" + + +@fixture +def cache_dir(): + return {"exists": False, "path": ""} + + +@fixture +def str_value(): + return "" + + +@fixture +def command(): + return "" + + +@fixture +def should_not(): + return False + + +@fixture +def user_input(): + return "" + + +@fixture +def config_data(config_path): + return load_config(config_path) + + +@fixture +def journal_name(): + return None + + +@fixture +def which_output_stream(): + return None + + +@fixture +def editor_input(): + return None + + +@fixture +def num_args(): + return None + + +@fixture +def parsed_output(): + return {"lang": None, "obj": None} + + +@fixture +def editor_state(): + return { + "command": "", + "intent": {"method": "r", "input": None}, + "tmpfile": {"name": None, "content": None}, + } + + +@fixture +def editor(editor_state): + def _mock_editor(editor_command): + tmpfile = editor_command[-1] + + editor_state["command"] = editor_command + editor_state["tmpfile"]["name"] = tmpfile + + Path(tmpfile).touch() + with open(tmpfile, editor_state["intent"]["method"]) as f: + # Touch the file so jrnl knows it was edited + if editor_state["intent"]["input"] is not None: + f.write(editor_state["intent"]["input"]) + + file_content = f.read() + editor_state["tmpfile"]["content"] = file_content + + return _mock_editor diff --git a/tests/lib/given_steps.py b/tests/lib/given_steps.py new file mode 100644 index 00000000..649d44c5 --- /dev/null +++ b/tests/lib/given_steps.py @@ -0,0 +1,134 @@ +# 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 ""')) +@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 ""', 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('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} diff --git a/tests/lib/helpers.py b/tests/lib/helpers.py new file mode 100644 index 00000000..7d089597 --- /dev/null +++ b/tests/lib/helpers.py @@ -0,0 +1,40 @@ +# Copyright (C) 2012-2021 jrnl contributors +# License: https://www.gnu.org/licenses/gpl-3.0.html + +import os + + +def does_directory_contain_files(file_list, directory_path): + if not os.path.isdir(directory_path): + return False + + for file in file_list.split("\n"): + fullpath = directory_path + "/" + file + if not os.path.isfile(fullpath): + return False + + return True + + +def parse_should_or_should_not(should_or_should_not): + if should_or_should_not == "should": + return True + elif should_or_should_not == "should not": + return False + else: + raise Exception( + "should_or_should_not valid values are 'should' or 'should not'" + ) + + +def assert_equal_tags_ignoring_order( + actual_line, expected_line, actual_content, expected_content +): + actual_tags = set(tag.strip() for tag in actual_line[len("tags: ") :].split(",")) + expected_tags = set( + tag.strip() for tag in expected_line[len("tags: ") :].split(",") + ) + assert actual_tags == expected_tags, [ + [actual_tags, expected_tags], + [expected_content, actual_content], + ] diff --git a/tests/lib/then_steps.py b/tests/lib/then_steps.py new file mode 100644 index 00000000..b56c203f --- /dev/null +++ b/tests/lib/then_steps.py @@ -0,0 +1,331 @@ +# Copyright (C) 2012-2021 jrnl contributors +# License: https://www.gnu.org/licenses/gpl-3.0.html + +import json +import os +import re +from xml.etree import ElementTree + +from pytest_bdd import then +from pytest_bdd.parsers import parse +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 + + +@then("we should get no error") +def should_get_no_error(cli_run): + assert cli_run["status"] == 0, cli_run["status"] + + +@then(parse('the output should match "{regex}"')) +def output_should_match(regex, cli_run): + out = cli_run["stdout"] + matches = re.findall(regex, out) + assert matches, f"\nRegex didn't match:\n{regex}\n{str(out)}\n{str(matches)}" + + +@then(parse("the output should contain\n{expected_output}")) +@then(parse('the output should contain "{expected_output}"')) +@then('the output should contain ""') +@then(parse("the {which_output_stream} output should contain\n{expected_output}")) +@then(parse('the {which_output_stream} output should contain "{expected_output}"')) +def output_should_contain(expected_output, which_output_stream, cli_run): + assert expected_output + if which_output_stream is None: + assert (expected_output in cli_run["stdout"]) or ( + expected_output in cli_run["stderr"] + ) + + elif which_output_stream == "standard": + assert expected_output in cli_run["stdout"] + + elif which_output_stream == "error": + assert expected_output in cli_run["stderr"] + + else: + assert expected_output in cli_run[which_output_stream] + + +@then(parse("the output should not contain\n{expected_output}")) +@then(parse('the output should not contain "{expected_output}"')) +@then('the output should not contain ""') +def output_should_not_contain(expected_output, cli_run): + assert expected_output not in cli_run["stdout"] + + +@then(parse("the output should be\n{expected_output}")) +@then(parse('the output should be "{expected_output}"')) +@then('the output should be ""') +def output_should_be(expected_output, cli_run): + actual = cli_run["stdout"].strip() + expected = expected_output.strip() + assert expected == actual + + +@then("the output should be empty") +def output_should_be_empty(cli_run): + actual = cli_run["stdout"].strip() + assert actual == "" + + +@then('the output should contain the date ""') +def output_should_contain_date(date, cli_run): + assert date and date in cli_run["stdout"] + + +@then("the output should contain pyproject.toml version") +def output_should_contain_version(cli_run, toml_version): + out = cli_run["stdout"] + assert toml_version in out, toml_version + + +@then(parse('we should see the message "{text}"')) +def should_see_the_message(text, cli_run): + out = cli_run["stderr"] + assert text in out, [text, out] + + +@then( + parse( + 'the config for journal "{journal_name}" {should_or_should_not} contain "{some_yaml}"' + ) +) +@then( + parse( + 'the config for journal "{journal_name}" {should_or_should_not} contain\n{some_yaml}' + ) +) +@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): + we_should = parse_should_or_should_not(should_or_should_not) + + actual = config_data + if journal_name: + actual = actual["journals"][journal_name] + + expected = yaml.load(some_yaml, Loader=yaml.FullLoader) + + actual_slice = actual + if type(actual) is dict: + actual_slice = {key: actual.get(key, None) 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 + + +@then("we should not be prompted for a password") +def password_was_not_called(cli_run): + assert not cli_run["mocks"]["getpass"].called + + +@then(parse("the cache directory should contain the files\n{file_list}")) +def assert_dir_contains_files(file_list, cache_dir): + assert does_directory_contain_files(file_list, cache_dir["path"]) + + +@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") + + 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) + + assert not does_directory_contain_files( + scoped_config["journal"], "." + ), f'Journal "{journal_name}" does exist' + + +@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") + expected_path = scoped_config["journal"] + + contains_files = does_directory_contain_files(expected_path, ".") + + if should_or_should_not == "should": + assert contains_files + elif should_or_should_not == "should not": + assert not contains_files + else: + raise Exception( + "should_or_should_not valid values are 'should' or 'should not'" + ) + + +@then(parse('the content of file "{file_path}" in the cache should be\n{file_content}')) +def content_of_file_should_be(file_path, file_content, cache_dir): + assert cache_dir["exists"] + expected_content = file_content.strip().splitlines() + + with open(os.path.join(cache_dir["path"], file_path), "r") as f: + actual_content = f.read().strip().splitlines() + + for actual_line, expected_line in zip(actual_content, expected_content): + if actual_line.startswith("tags: ") and expected_line.startswith("tags: "): + assert_equal_tags_ignoring_order( + actual_line, expected_line, actual_content, expected_content + ) + else: + assert actual_line.strip() == expected_line.strip(), [ + [actual_line.strip(), expected_line.strip()], + [actual_content, expected_content], + ] + + +@then(parse("the cache should contain the files\n{file_list}")) +def cache_dir_contains_files(file_list, cache_dir): + assert cache_dir["exists"] + + actual_files = os.listdir(cache_dir["path"]) + expected_files = file_list.split("\n") + + # sort to deal with inconsistent default file ordering on different OS's + actual_files.sort() + expected_files.sort() + + assert actual_files == expected_files, [actual_files, expected_files] + + +@then(parse("the output should be valid {language_name}")) +def assert_output_is_valid_language(cli_run, language_name): + language_name = language_name.upper() + if language_name == "XML": + xml_tree = ElementTree.fromstring(cli_run["stdout"]) + assert xml_tree, "Invalid XML" + elif language_name == "JSON": + assert json.loads(cli_run["stdout"]), "Invalid JSON" + else: + assert False, f"Language name {language_name} not recognized" + + +@then(parse('"{node_name}" in the parsed output should have {number:d} elements')) +def assert_parsed_output_item_count(node_name, number, parsed_output): + lang = parsed_output["lang"] + obj = parsed_output["obj"] + + if lang == "XML": + xml_node_names = (node.tag for node in obj) + assert node_name in xml_node_names, str(list(xml_node_names)) + + actual_entry_count = len(obj.find(node_name)) + assert actual_entry_count == number, actual_entry_count + + elif lang == "JSON": + my_obj = obj + + for node in node_name.split("."): + try: + my_obj = my_obj[int(node)] + except ValueError: + assert node in my_obj + my_obj = my_obj[node] + + assert len(my_obj) == number, len(my_obj) + + else: + assert False, f"Language name {lang} not recognized" + + +@then(parse('"{field_name}" in the parsed output should {comparison}\n{expected_keys}')) +def assert_output_field_content(field_name, comparison, expected_keys, parsed_output): + lang = parsed_output["lang"] + obj = parsed_output["obj"] + expected_keys = expected_keys.split("\n") + if len(expected_keys) == 1: + expected_keys = expected_keys[0] + + if lang == "XML": + xml_node_names = (node.tag for node in obj) + assert field_name in xml_node_names, str(list(xml_node_names)) + + if field_name == "tags": + actual_tags = set(t.attrib["name"] for t in obj.find("tags")) + assert set(actual_tags) == set(expected_keys), [ + actual_tags, + set(expected_keys), + ] + else: + assert False, "This test only works for tags in XML" + + elif lang == "JSON": + my_obj = obj + + for node in field_name.split("."): + try: + my_obj = my_obj[int(node)] + except ValueError: + assert node in my_obj, [my_obj.keys(), node] + my_obj = my_obj[node] + + if comparison == "be": + if type(my_obj) is str: + assert expected_keys == my_obj, [my_obj, expected_keys] + else: + assert set(expected_keys) == set(my_obj), [ + set(my_obj), + set(expected_keys), + ] + elif comparison == "contain": + if type(my_obj) is str: + assert expected_keys in my_obj, [my_obj, expected_keys] + else: + assert all(elem in my_obj for elem in expected_keys), [ + my_obj, + expected_keys, + ] + else: + assert False, f"Language name {lang} not recognized" + + +@then(parse('there should be {number:d} "{item}" elements')) +def count_elements(number, item, cli_run): + actual_output = cli_run["stdout"] + xml_tree = ElementTree.fromstring(actual_output) + 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 + + if isinstance(num_args, int): + assert len(editor_state["command"]) == int(num_args) + + +@then(parse('the editor filename should end with "{suffix}"')) +def editor_filename_suffix(suffix, editor_state): + editor_filename = editor_state["tmpfile"]["name"] + + assert editor_state["tmpfile"]["name"].endswith(suffix), (editor_filename, suffix) + + +@then(parse('the editor file content should {comparison} "{str_value}"')) +@then(parse("the editor file content should {comparison} empty")) +@then(parse("the editor file content should {comparison}\n{str_value}")) +def contains_editor_file(comparison, str_value, editor_state): + content = editor_state["tmpfile"]["content"] + # content = f'\n"""\n{content}\n"""\n' + if comparison == "be": + assert content == str_value + elif comparison == "contain": + assert str_value in content + else: + assert False, f"Comparison '{comparison}' not supported" diff --git a/tests/lib/when_steps.py b/tests/lib/when_steps.py new file mode 100644 index 00000000..2e72173b --- /dev/null +++ b/tests/lib/when_steps.py @@ -0,0 +1,113 @@ +# Copyright (C) 2012-2021 jrnl contributors +# License: https://www.gnu.org/licenses/gpl-3.0.html + +from contextlib import ExitStack +import os +from unittest.mock import patch + +from pytest_bdd import parsers +from pytest_bdd import when +from pytest_bdd.parsers import parse + +from jrnl.cli import cli +from jrnl.os_compat import split_args + + +@when(parse('we change directory to "{directory_name}"')) +def when_we_change_directory(directory_name): + if not os.path.isdir(directory_name): + os.mkdir(directory_name) + + os.chdir(directory_name) + + +@when(parse('we run "jrnl {command}" and {input_method}\n{user_input}')) +@when( + parsers.re( + 'we run "jrnl (?P[^"]+)" and (?Penter|pipe) "(?P[^"]+)"' + ) +) +@when(parse('we run "jrnl" and {input_method} "{user_input}"')) +@when(parse('we run "jrnl {command}"')) +@when('we run "jrnl "') +@when('we run "jrnl"') +def we_run( + command, + config_path, + user_input, + cli_run, + capsys, + password, + cache_dir, + editor, + keyring, + input_method, + mocks, +): + assert input_method in ["", "enter", "pipe"] + is_tty = input_method != "pipe" + + if cache_dir["exists"]: + command = command.format(cache_dir=cache_dir["path"]) + + args = split_args(command) + status = 0 + + if user_input: + user_input = user_input.splitlines() if is_tty else [user_input] + + if password: + password = password.splitlines() + + if not password and user_input: + password = user_input + + with ExitStack() as stack: + + stack.enter_context(patch("sys.argv", ["jrnl"] + args)) + + mock_stdin = stack.enter_context( + patch("sys.stdin.read", side_effect=user_input) + ) + stack.enter_context(patch("sys.stdin.isatty", return_value=is_tty)) + mock_input = stack.enter_context( + patch("builtins.input", side_effect=user_input) + ) + mock_getpass = stack.enter_context( + patch("getpass.getpass", side_effect=password) + ) + + if "datetime" in mocks: + stack.enter_context(mocks["datetime"]) + stack.enter_context(mocks["calendar_parse"]) + + # stack.enter_context(patch("datetime.datetime", new=mocks["datetime"])) + # stack.enter_context(patch("jrnl.time.__get_pdt_calendar", return_value=mocks["calendar_parse"])) + + stack.enter_context( + patch("jrnl.install.get_config_path", return_value=config_path) + ) + stack.enter_context( + patch("jrnl.config.get_config_path", return_value=config_path) + ) + mock_editor = stack.enter_context(patch("subprocess.call", side_effect=editor)) + + try: + cli(args) + except StopIteration: + # This happens when input is expected, but don't have any input left + pass + except SystemExit as e: + status = e.code + + captured = capsys.readouterr() + + cli_run["status"] = status + cli_run["stdout"] = captured.out + cli_run["stderr"] = captured.err + cli_run["mocks"] = { + "stdin": mock_stdin, + "input": mock_input, + "getpass": mock_getpass, + "editor": mock_editor, + } From 495956d907486ce86106696e0ecf1fe314644dc4 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 3 Jul 2021 15:21:41 -0700 Subject: [PATCH 154/215] remove init file that is no longer neded --- __init__.py | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 __init__.py diff --git a/__init__.py b/__init__.py deleted file mode 100644 index 46468510..00000000 --- a/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -import sys - -sys.path.append("..") From 26484130c3214e34b15b42a494deb4532b585fa1 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 3 Jul 2021 15:21:50 -0700 Subject: [PATCH 155/215] remove old comment --- tests/lib/when_steps.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/lib/when_steps.py b/tests/lib/when_steps.py index 2e72173b..642249e9 100644 --- a/tests/lib/when_steps.py +++ b/tests/lib/when_steps.py @@ -81,9 +81,6 @@ def we_run( stack.enter_context(mocks["datetime"]) stack.enter_context(mocks["calendar_parse"]) - # stack.enter_context(patch("datetime.datetime", new=mocks["datetime"])) - # stack.enter_context(patch("jrnl.time.__get_pdt_calendar", return_value=mocks["calendar_parse"])) - stack.enter_context( patch("jrnl.install.get_config_path", return_value=config_path) ) From 9e3153453eabf0659ce47985e922cf97cc1584a1 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 3 Jul 2021 15:50:36 -0700 Subject: [PATCH 156/215] Change all instances of FullLoader to SafeLoader (#1285) --- features/steps/core.py | 8 ++++---- jrnl/config.py | 4 ++-- jrnl/plugins/template.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/features/steps/core.py b/features/steps/core.py index ac5d8950..2ad5bcc4 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -17,7 +17,7 @@ import keyring import toml import yaml -from yaml.loader import FullLoader +from yaml.loader import SafeLoader import jrnl.time @@ -409,7 +409,7 @@ def run(context, command, text=""): if "config_path" in context and context.config_path is not None: with open(context.config_path) as f: - context.jrnl_config = yaml.load(f, Loader=yaml.FullLoader) + context.jrnl_config = yaml.load(f, Loader=yaml.SafeLoader) else: context.jrnl_config = None @@ -418,7 +418,7 @@ def run(context, command, text=""): command = command.format(cache_dir=cache_dir) if "config_path" in context and context.config_path is not None: with open(context.config_path, "r") as f: - cfg = yaml.load(f, Loader=FullLoader) + cfg = yaml.load(f, Loader=SafeLoader) context.jrnl_config = cfg args = split_args(command) @@ -675,7 +675,7 @@ def check_journal_entries(context, number, journal_name="default"): @when("the journal directory is listed") def list_journal_directory(context, journal="default"): with open(context.config_path) as config_file: - configuration = yaml.load(config_file, Loader=yaml.FullLoader) + configuration = yaml.load(config_file, Loader=yaml.SafeLoader) journal_path = configuration["journals"][journal] for root, dirnames, f in os.walk(journal_path): for file in f: diff --git a/jrnl/config.py b/jrnl/config.py index da2df2cc..32695204 100644 --- a/jrnl/config.py +++ b/jrnl/config.py @@ -41,7 +41,7 @@ def make_yaml_valid_dict(input: list) -> dict: # yaml compatible strings are of the form Key:Value yamlstr = YAML_SEPARATOR.join(input) - runtime_modifications = yaml.load(yamlstr, Loader=yaml.FullLoader) + runtime_modifications = yaml.load(yamlstr, Loader=yaml.SafeLoader) return runtime_modifications @@ -140,7 +140,7 @@ def verify_config_colors(config): def load_config(config_path): """Tries to load a config file from YAML.""" with open(config_path) as f: - return yaml.load(f, Loader=yaml.FullLoader) + return yaml.load(f, Loader=yaml.SafeLoader) def is_config_json(config_path): diff --git a/jrnl/plugins/template.py b/jrnl/plugins/template.py index 147cd7af..cb852471 100644 --- a/jrnl/plugins/template.py +++ b/jrnl/plugins/template.py @@ -26,7 +26,7 @@ class Template: def from_file(cls, filename): with open(filename) as f: front_matter, body = f.read().strip("-\n").split("---", 2) - front_matter = yaml.load(front_matter, Loader=yaml.FullLoader) + front_matter = yaml.load(front_matter, Loader=yaml.SafeLoader) template = cls(body) template.__dict__.update(front_matter) return template From 56df419bea3750fa7156dec80a6850a6f906944c Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 3 Jul 2021 22:52:14 +0000 Subject: [PATCH 157/215] Update changelog [ci skip] --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8f71a70..e7700ab4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,10 @@ **Build:** +- Move test suite entirely to Pytest \(replace Behave\) [\#1192](https://github.com/jrnl-org/jrnl/issues/1192) - Remove useless shebangs and executable permissions [\#1283](https://github.com/jrnl-org/jrnl/pull/1283) ([musicinmybrain](https://github.com/musicinmybrain)) - Remove `--version` from brew release workflow [\#1233](https://github.com/jrnl-org/jrnl/pull/1233) ([wren](https://github.com/wren)) +- Move test suite to Pytest \(replace Behave\) [\#1193](https://github.com/jrnl-org/jrnl/pull/1193) ([wren](https://github.com/wren)) **Packaging:** From 2723e1cfb55d2af965b8b0bded4b24ebcbffe6f1 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 10 Jul 2021 12:13:15 -0700 Subject: [PATCH 158/215] Add Python 3.10 support (#1271) * Add Python 3.10 support * Change Python 3.10 to 3.10-dev in CI * Run poetry update * Turn off fail-fast to troubleshoot Co-authored-by: Jonathan Wren * Add continue-on-error for 3.10 Co-authored-by: Jonathan Wren * use prerelease poetry for prerelease python * fix syntax error * rename steps to make more sense * remove dev dependency that breaks with python 3.10 * update tests * Change test dependencies for minimal breakage on python 3.10 - loosen the test dep requirements (so we get warned about these problems sooner) - add new extras group to provide minimal deps required for testing (we don't need to run static analysis again on every version) * change how we check if deps are installed so test don't run wild * add setuptools due to poetry bug, clean up other steps * update lock file * test * Revert "test" This reverts commit 31e538300ef7f2ab3ff84da7fe03f156e4714e06. Co-authored-by: Jonathan Wren --- .github/workflows/testing.yaml | 41 +++++- poetry.lock | 260 +++++++++++++++++---------------- pyproject.toml | 27 +++- 3 files changed, 188 insertions(+), 140 deletions(-) diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index 47710ca2..396fc854 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -23,9 +23,11 @@ jobs: if: > ! contains(github.event.head_commit.message, '[ci skip]') runs-on: ${{ matrix.os }} + continue-on-error: ${{ matrix.python-version == '3.10-dev' }} strategy: + fail-fast: false matrix: - python-version: [ 3.7, 3.8, 3.9 ] + python-version: [ 3.7, 3.8, 3.9, 3.10-dev ] os: [ ubuntu-latest, macos-latest, windows-latest ] steps: @@ -44,27 +46,50 @@ jobs: key: ${{ runner.os }}-${{ hashFiles('poetry.lock') }}-${{ matrix.python-version }}-v2 - name: Install dependencies + if: ${{ matrix.python-version != '3.10-dev' }} run: | + echo '::group::poetry' pip install poetry poetry config --local virtualenvs.in-project true + echo '::endgroup::' + + echo '::group::Other dependencies' poetry install --remove-untracked + echo '::endgroup::' + + echo 'DEPS_INSTALLED=true' >> $GITHUB_ENV + + + - name: Install dependencies (Prerelease) + if: ${{ matrix.python-version == '3.10-dev' }} + run: | + echo '::group::poetry' + pip install poetry==1.2.0a1 + poetry config --local virtualenvs.in-project true + echo '::endgroup::' + + echo '::group::Other dependencies' + poetry install --remove-untracked --no-dev --extras testing + echo '::endgroup::' + + echo 'DEPS_INSTALLED=true' >> $GITHUB_ENV - name: Code formatting (Black) - if: success() || failure() + if: ${{ matrix.python-version != '3.10-dev' && env.DEPS_INSTALLED == 'true' }} run: | poetry run black --version poetry run black --check --diff . - - name: Code Style (PyFlakes) - if: success() || failure() + - name: Code Style (flake8) + if: ${{ matrix.python-version != '3.10-dev' && env.DEPS_INSTALLED == 'true' }} run: | - poetry run pyflakes --version - poetry run pyflakes jrnl features tests + poetry run pflake8 --version + poetry run pflake8 jrnl features tests - name: Test with pytest - if: success() || failure() + if: ${{ env.DEPS_INSTALLED == 'true' }} run: poetry run pytest --junitxml=reports/pytest/results.xml - name: Test with behave - if: success() || failure() + if: ${{ env.DEPS_INSTALLED == 'true' }} run: poetry run behave --no-skipped --format progress2 --junit --junit-directory reports/behave diff --git a/poetry.lock b/poetry.lock index 2d1a8ea2..172a2533 100644 --- a/poetry.lock +++ b/poetry.lock @@ -25,20 +25,6 @@ category = "dev" optional = false python-versions = "*" -[[package]] -name = "argcomplete" -version = "1.12.3" -description = "Bash tab completion for argparse" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -importlib-metadata = {version = ">=0.23,<5", markers = "python_version == \"3.7\""} - -[package.extras] -test = ["coverage", "flake8", "pexpect", "wheel"] - [[package]] name = "asteval" version = "0.9.25" @@ -51,7 +37,7 @@ python-versions = ">=3.6" name = "atomicwrites" version = "1.4.0" description = "Atomic file writes." -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" @@ -59,7 +45,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" name = "attrs" version = "21.2.0" description = "Classes Without Boilerplate" -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" @@ -81,7 +67,7 @@ python-versions = "*" name = "behave" version = "1.2.6" description = "behave is behaviour-driven development, Python style" -category = "dev" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" @@ -149,6 +135,17 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "commonmark" +version = "0.9.1" +description = "Python parser for the CommonMark Markdown spec" +category = "dev" +optional = false +python-versions = "*" + +[package.extras] +test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] + [[package]] name = "cryptography" version = "3.4.7" @@ -208,13 +205,13 @@ dev = ["twine", "markdown", "flake8"] name = "glob2" version = "0.7" description = "Version of the glob module that can capture patterns and supports recursive wildcards" -category = "dev" +category = "main" optional = false python-versions = "*" [[package]] name = "importlib-metadata" -version = "4.6.0" +version = "4.6.1" description = "Read metadata from Python packages" category = "main" optional = false @@ -233,7 +230,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes name = "iniconfig" version = "1.1.1" description = "iniconfig: brain-dead simple config-ini parsing" -category = "dev" +category = "main" optional = false python-versions = "*" @@ -248,6 +245,7 @@ python-versions = ">=2.7" [package.dependencies] decorator = {version = "*", markers = "python_version > \"3.6\""} ipython = {version = ">=7.17.0", markers = "python_version > \"3.6\""} +setuptools = "*" toml = {version = ">=0.10.2", markers = "python_version > \"3.6\""} [[package]] @@ -269,6 +267,7 @@ pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} pickleshare = "*" prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" pygments = "*" +setuptools = ">=18.5" traitlets = ">=4.2" [package.extras] @@ -352,7 +351,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes name = "mako" version = "1.1.4" description = "A super-fast templating language that borrows the best ideas from the existing templating languages." -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" @@ -381,7 +380,7 @@ testing = ["coverage", "pyyaml"] name = "markupsafe" version = "2.0.1" description = "Safely add untrusted strings to HTML/XML markup." -category = "dev" +category = "main" optional = false python-versions = ">=3.6" @@ -447,7 +446,7 @@ python-versions = "*" name = "packaging" version = "21.0" description = "Core utilities for Python packages" -category = "dev" +category = "main" optional = false python-versions = ">=3.6" @@ -458,7 +457,7 @@ pyparsing = ">=2.0.2" name = "parse" version = "1.19.0" description = "parse() is the opposite of format()" -category = "dev" +category = "main" optional = false python-versions = "*" @@ -466,7 +465,7 @@ python-versions = "*" name = "parse-type" version = "0.5.2" description = "Simplifies to build parse types based on the parse module" -category = "dev" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*" @@ -529,7 +528,7 @@ python-versions = "*" name = "pluggy" version = "0.13.1" description = "plugin and hook calling mechanisms for python" -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" @@ -539,6 +538,14 @@ importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} [package.extras] dev = ["pre-commit", "tox"] +[[package]] +name = "pprintpp" +version = "0.4.0" +description = "A drop-in replacement for pprint that's actually pretty" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "prompt-toolkit" version = "3.0.19" @@ -562,7 +569,7 @@ python-versions = "*" name = "py" version = "1.10.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" @@ -602,7 +609,7 @@ python-versions = ">=3.5" name = "pyparsing" version = "2.4.7" description = "Python parsing module" -category = "dev" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" @@ -622,7 +629,7 @@ toml = "*" name = "pytest" version = "6.2.4" description = "pytest: simple powerful testing with Python" -category = "dev" +category = "main" optional = false python-versions = ">=3.6" @@ -644,7 +651,7 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xm name = "pytest-bdd" version = "4.1.0" description = "BDD for pytest" -category = "dev" +category = "main" optional = false python-versions = ">=3.6" @@ -658,15 +665,16 @@ pytest = ">=4.3" [[package]] name = "pytest-clarity" -version = "0.3.0a0" +version = "1.0.1" description = "A plugin providing an alternative, colourful diff output for failing assertions." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] +pprintpp = ">=0.4.0" pytest = ">=3.5.0" -termcolor = "1.1.0" +rich = ">=8.0.0" [[package]] name = "python-dateutil" @@ -724,12 +732,29 @@ pyyaml = "*" [[package]] name = "regex" -version = "2021.7.1" +version = "2021.7.6" description = "Alternative regular expression module, to replace re." category = "dev" optional = false python-versions = "*" +[[package]] +name = "rich" +version = "10.5.0" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +category = "dev" +optional = false +python-versions = ">=3.6,<4.0" + +[package.dependencies] +colorama = ">=0.4.0,<0.5.0" +commonmark = ">=0.9.0,<0.10.0" +pygments = ">=2.6.0,<3.0.0" +typing-extensions = {version = ">=3.7.4,<4.0.0", markers = "python_version < \"3.8\""} + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] + [[package]] name = "secretstorage" version = "3.3.1" @@ -742,6 +767,18 @@ python-versions = ">=3.6" cryptography = ">=2.0" jeepney = ">=0.6" +[[package]] +name = "setuptools" +version = "57.1.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "pygments-github-lexers (==0.0.5)", "sphinx-inline-tabs", "sphinxcontrib-towncrier"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "mock", "flake8-2020", "virtualenv (>=13.0.0)", "pytest-virtualenv (>=1.2.7)", "wheel", "paver", "pip (>=19.1)", "jaraco.envs", "pytest-xdist", "sphinx", "jaraco.path (>=3.2.0)", "pytest-black (>=0.3.7)", "pytest-mypy"] + [[package]] name = "six" version = "1.16.0" @@ -750,14 +787,6 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -[[package]] -name = "termcolor" -version = "1.1.0" -description = "ANSII Color formatting for output in terminal." -category = "dev" -optional = false -python-versions = "*" - [[package]] name = "textwrap3" version = "0.9.2" @@ -770,7 +799,7 @@ python-versions = "*" name = "toml" version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" -category = "dev" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" @@ -834,31 +863,6 @@ category = "dev" optional = false python-versions = "*" -[[package]] -name = "xmltodict" -version = "0.12.0" -description = "Makes working with XML feel like you are working with JSON" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[[package]] -name = "yq" -version = "2.12.2" -description = "Command-line YAML/XML processor - jq wrapper for YAML/XML documents" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -argcomplete = ">=1.8.1" -PyYAML = ">=3.11" -toml = ">=0.10.0" -xmltodict = ">=0.11.0" - -[package.extras] -test = ["coverage", "flake8", "wheel"] - [[package]] name = "zipp" version = "3.5.0" @@ -871,10 +875,13 @@ python-versions = ">=3.6" docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +[extras] +testing = ["behave", "pytest", "pytest-bdd", "toml"] + [metadata] lock-version = "1.1" -python-versions = ">=3.7.0, <3.10" -content-hash = "5be8c38e248b64ff4f2eacf253411b57c91352523c40674f1dec6d8c304996c2" +python-versions = ">=3.7.0, <3.11" +content-hash = "8549770f6a13b58f3baf9b434b326fc6bfc69eaccd604efcce110744fabdac64" [metadata.files] ansiwrap = [ @@ -889,10 +896,6 @@ appnope = [ {file = "appnope-0.1.2-py2.py3-none-any.whl", hash = "sha256:93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442"}, {file = "appnope-0.1.2.tar.gz", hash = "sha256:dd83cd4b5b460958838f6eb3000c660b1f9caf2a5b1de4264e941512f603258a"}, ] -argcomplete = [ - {file = "argcomplete-1.12.3-py2.py3-none-any.whl", hash = "sha256:291f0beca7fd49ce285d2f10e4c1c77e9460cf823eef2de54df0c0fec88b0d81"}, - {file = "argcomplete-1.12.3.tar.gz", hash = "sha256:2c7dbffd8c045ea534921e63b0be6fe65e88599990d8dc408ac8c542b72a5445"}, -] asteval = [ {file = "asteval-0.9.25.tar.gz", hash = "sha256:bea22b7d8fa16bcba95ebc72052ae5d8ca97114c9959bb47f8b8eebf30e4342f"}, ] @@ -963,6 +966,10 @@ colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] +commonmark = [ + {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, + {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, +] cryptography = [ {file = "cryptography-3.4.7-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:3d8427734c781ea5f1b41d6589c293089704d4759e34597dce91014ac125aad1"}, {file = "cryptography-3.4.7-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:8e56e16617872b0957d1c9742a3f94b43533447fd78321514abbe7db216aa250"}, @@ -992,8 +999,8 @@ glob2 = [ {file = "glob2-0.7.tar.gz", hash = "sha256:85c3dbd07c8aa26d63d7aacee34fa86e9a91a3873bc30bf62ec46e531f92ab8c"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.6.0-py3-none-any.whl", hash = "sha256:c6513572926a96458f8c8f725bf0e00108fba0c9583ade9bd15b869c9d726e33"}, - {file = "importlib_metadata-4.6.0.tar.gz", hash = "sha256:4a5611fea3768d3d967c447ab4e93f567d95db92225b43b7b238dbfb855d70bb"}, + {file = "importlib_metadata-4.6.1-py3-none-any.whl", hash = "sha256:9f55f560e116f8643ecf2922d9cd3e1c7e8d52e683178fecd9d08f6aa357e11e"}, + {file = "importlib_metadata-4.6.1.tar.gz", hash = "sha256:079ada16b7fc30dfbb5d13399a5113110dab1aa7c2bc62f66af75f0b717c8cac"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -1124,6 +1131,10 @@ pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, ] +pprintpp = [ + {file = "pprintpp-0.4.0-py2.py3-none-any.whl", hash = "sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d"}, + {file = "pprintpp-0.4.0.tar.gz", hash = "sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403"}, +] prompt-toolkit = [ {file = "prompt_toolkit-3.0.19-py3-none-any.whl", hash = "sha256:7089d8d2938043508aa9420ec18ce0922885304cddae87fb96eebca942299f88"}, {file = "prompt_toolkit-3.0.19.tar.gz", hash = "sha256:08360ee3a3148bdb5163621709ee322ec34fc4375099afa4bbf751e9b7b7fa4f"}, @@ -1169,7 +1180,7 @@ pytest-bdd = [ {file = "pytest_bdd-4.1.0-py3-none-any.whl", hash = "sha256:7c5221680cec9a97630e1fae6132f4a97c2f86a90914206ee06a55ae1a409fe5"}, ] pytest-clarity = [ - {file = "pytest-clarity-0.3.0a0.tar.gz", hash = "sha256:5cc99e3d9b7969dfe17e5f6072d45a917c59d363b679686d3c958a1ded2e4dcf"}, + {file = "pytest-clarity-1.0.1.tar.gz", hash = "sha256:505fe345fad4fe11c6a4187fe683f2c7c52c077caa1e135f3e483fe112db7772"}, ] python-dateutil = [ {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, @@ -1215,55 +1226,64 @@ pyyaml-env-tag = [ {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, ] regex = [ - {file = "regex-2021.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:494d0172774dc0beeea984b94c95389143db029575f7ca908edd74469321ea99"}, - {file = "regex-2021.7.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:8cf6728f89b071bd3ab37cb8a0e306f4de897553a0ed07442015ee65fbf53d62"}, - {file = "regex-2021.7.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1806370b2bef4d4193eebe8ee59a9fd7547836a34917b7badbe6561a8594d9cb"}, - {file = "regex-2021.7.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d0cf2651a8804f6325747c7e55e3be0f90ee2848e25d6b817aa2728d263f9abb"}, - {file = "regex-2021.7.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:268fe9dd1deb4a30c8593cabd63f7a241dfdc5bd9dd0233906c718db22cdd49a"}, - {file = "regex-2021.7.1-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:7743798dfb573d006f1143d745bf17efad39775a5190b347da5d83079646be56"}, - {file = "regex-2021.7.1-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:0e46c1191b2eb293a6912269ed08b4512e7e241bbf591f97e527492e04c77e93"}, - {file = "regex-2021.7.1-cp36-cp36m-win32.whl", hash = "sha256:b1dbeef938281f240347d50f28ae53c4b046a23389cd1fc4acec5ea0eae646a1"}, - {file = "regex-2021.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:6c72ebb72e64e9bd195cb35a9b9bbfb955fd953b295255b8ae3e4ad4a146b615"}, - {file = "regex-2021.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bf819c5b77ff44accc9a24e31f1f7ceaaf6c960816913ed3ef8443b9d20d81b6"}, - {file = "regex-2021.7.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:e80d2851109e56420b71f9702ad1646e2f0364528adbf6af85527bc61e49f394"}, - {file = "regex-2021.7.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a1b6a3f600d6aff97e3f28c34192c9ed93fee293bd96ef327b64adb51a74b2f6"}, - {file = "regex-2021.7.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:ed77b97896312bc2deafe137ca2626e8b63808f5bedb944f73665c68093688a7"}, - {file = "regex-2021.7.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:a548bb51c4476332ce4139df8e637386730f79a92652a907d12c696b6252b64d"}, - {file = "regex-2021.7.1-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:210c359e6ee5b83f7d8c529ba3c75ba405481d50f35a420609b0db827e2e3bb5"}, - {file = "regex-2021.7.1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:1d386402ae7f3c9b107ae5863f7ecccb0167762c82a687ae6526b040feaa5ac6"}, - {file = "regex-2021.7.1-cp37-cp37m-win32.whl", hash = "sha256:5049d00dbb78f9d166d1c704e93934d42cce0570842bb1a61695123d6b01de09"}, - {file = "regex-2021.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:361be4d311ac995a8c7ad577025a3ae3a538531b1f2cf32efd8b7e5d33a13e5a"}, - {file = "regex-2021.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f32f47fb22c988c0b35756024b61d156e5c4011cb8004aa53d93b03323c45657"}, - {file = "regex-2021.7.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:b024ee43ee6b310fad5acaee23e6485b21468718cb792a9d1693eecacc3f0b7e"}, - {file = "regex-2021.7.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:b092754c06852e8a8b022004aff56c24b06310189186805800d09313c37ce1f8"}, - {file = "regex-2021.7.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:a8a5826d8a1b64e2ff9af488cc179e1a4d0f144d11ce486a9f34ea38ccedf4ef"}, - {file = "regex-2021.7.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:444723ebaeb7fa8125f29c01a31101a3854ac3de293e317944022ae5effa53a4"}, - {file = "regex-2021.7.1-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:fdad3122b69cdabdb3da4c2a4107875913ac78dab0117fc73f988ad589c66b66"}, - {file = "regex-2021.7.1-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:4b1999ef60c45357598935c12508abf56edbbb9c380df6f336de38a6c3a294ae"}, - {file = "regex-2021.7.1-cp38-cp38-win32.whl", hash = "sha256:e07e92935040c67f49571779d115ecb3e727016d42fb36ee0d8757db4ca12ee0"}, - {file = "regex-2021.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:6b8b629f93246e507287ee07e26744beaffb4c56ed520576deac8b615bd76012"}, - {file = "regex-2021.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:56bef6b414949e2c9acf96cb5d78de8b529c7b99752619494e78dc76f99fd005"}, - {file = "regex-2021.7.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:78a2a885345a2d60b5e68099e877757d5ed12e46ba1e87507175f14f80892af3"}, - {file = "regex-2021.7.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:3f7a92e60930f8fca2623d9e326c173b7cf2c8b7e4fdcf984b75a1d2fb08114d"}, - {file = "regex-2021.7.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4fc86b729ab88fe8ac3ec92287df253c64aa71560d76da5acd8a2e245839c629"}, - {file = "regex-2021.7.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:59845101de68fd5d3a1145df9ea022e85ecd1b49300ea68307ad4302320f6f61"}, - {file = "regex-2021.7.1-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:ce269e903b00d1ab4746793e9c50a57eec5d5388681abef074d7b9a65748fca5"}, - {file = "regex-2021.7.1-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:c11f2fca544b5e30a0e813023196a63b1cb9869106ef9a26e9dae28bce3e4e26"}, - {file = "regex-2021.7.1-cp39-cp39-win32.whl", hash = "sha256:1ccbd41dbee3a31e18938096510b7d4ee53aa9fce2ee3dcc8ec82ae264f6acfd"}, - {file = "regex-2021.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:18040755606b0c21281493ec309214bd61e41a170509e5014f41d6a5a586e161"}, - {file = "regex-2021.7.1.tar.gz", hash = "sha256:849802379a660206277675aa5a5c327f5c910c690649535863ddf329b0ba8c87"}, + {file = "regex-2021.7.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e6a1e5ca97d411a461041d057348e578dc344ecd2add3555aedba3b408c9f874"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:6afe6a627888c9a6cfbb603d1d017ce204cebd589d66e0703309b8048c3b0854"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ccb3d2190476d00414aab36cca453e4596e8f70a206e2aa8db3d495a109153d2"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:ed693137a9187052fc46eedfafdcb74e09917166362af4cc4fddc3b31560e93d"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:99d8ab206a5270c1002bfcf25c51bf329ca951e5a169f3b43214fdda1f0b5f0d"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:b85ac458354165405c8a84725de7bbd07b00d9f72c31a60ffbf96bb38d3e25fa"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:3f5716923d3d0bfb27048242a6e0f14eecdb2e2a7fac47eda1d055288595f222"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5983c19d0beb6af88cb4d47afb92d96751fb3fa1784d8785b1cdf14c6519407"}, + {file = "regex-2021.7.6-cp36-cp36m-win32.whl", hash = "sha256:c92831dac113a6e0ab28bc98f33781383fe294df1a2c3dfd1e850114da35fd5b"}, + {file = "regex-2021.7.6-cp36-cp36m-win_amd64.whl", hash = "sha256:791aa1b300e5b6e5d597c37c346fb4d66422178566bbb426dd87eaae475053fb"}, + {file = "regex-2021.7.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:59506c6e8bd9306cd8a41511e32d16d5d1194110b8cfe5a11d102d8b63cf945d"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:564a4c8a29435d1f2256ba247a0315325ea63335508ad8ed938a4f14c4116a5d"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:59c00bb8dd8775473cbfb967925ad2c3ecc8886b3b2d0c90a8e2707e06c743f0"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:9a854b916806c7e3b40e6616ac9e85d3cdb7649d9e6590653deb5b341a736cec"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:db2b7df831c3187a37f3bb80ec095f249fa276dbe09abd3d35297fc250385694"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:173bc44ff95bc1e96398c38f3629d86fa72e539c79900283afa895694229fe6a"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:15dddb19823f5147e7517bb12635b3c82e6f2a3a6b696cc3e321522e8b9308ad"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ddeabc7652024803666ea09f32dd1ed40a0579b6fbb2a213eba590683025895"}, + {file = "regex-2021.7.6-cp37-cp37m-win32.whl", hash = "sha256:f080248b3e029d052bf74a897b9d74cfb7643537fbde97fe8225a6467fb559b5"}, + {file = "regex-2021.7.6-cp37-cp37m-win_amd64.whl", hash = "sha256:d8bbce0c96462dbceaa7ac4a7dfbbee92745b801b24bce10a98d2f2b1ea9432f"}, + {file = "regex-2021.7.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:edd1a68f79b89b0c57339bce297ad5d5ffcc6ae7e1afdb10f1947706ed066c9c"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux1_i686.whl", hash = "sha256:422dec1e7cbb2efbbe50e3f1de36b82906def93ed48da12d1714cabcd993d7f0"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:cbe23b323988a04c3e5b0c387fe3f8f363bf06c0680daf775875d979e376bd26"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:0eb2c6e0fcec5e0f1d3bcc1133556563222a2ffd2211945d7b1480c1b1a42a6f"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:1c78780bf46d620ff4fff40728f98b8afd8b8e35c3efd638c7df67be2d5cddbf"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:bc84fb254a875a9f66616ed4538542fb7965db6356f3df571d783f7c8d256edd"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:598c0a79b4b851b922f504f9f39a863d83ebdfff787261a5ed061c21e67dd761"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875c355360d0f8d3d827e462b29ea7682bf52327d500a4f837e934e9e4656068"}, + {file = "regex-2021.7.6-cp38-cp38-win32.whl", hash = "sha256:e586f448df2bbc37dfadccdb7ccd125c62b4348cb90c10840d695592aa1b29e0"}, + {file = "regex-2021.7.6-cp38-cp38-win_amd64.whl", hash = "sha256:2fe5e71e11a54e3355fa272137d521a40aace5d937d08b494bed4529964c19c4"}, + {file = "regex-2021.7.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6110bab7eab6566492618540c70edd4d2a18f40ca1d51d704f1d81c52d245026"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux1_i686.whl", hash = "sha256:4f64fc59fd5b10557f6cd0937e1597af022ad9b27d454e182485f1db3008f417"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:89e5528803566af4df368df2d6f503c84fbfb8249e6631c7b025fe23e6bd0cde"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2366fe0479ca0e9afa534174faa2beae87847d208d457d200183f28c74eaea59"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:f9392a4555f3e4cb45310a65b403d86b589adc773898c25a39184b1ba4db8985"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:2bceeb491b38225b1fee4517107b8491ba54fba77cf22a12e996d96a3c55613d"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:f98dc35ab9a749276f1a4a38ab3e0e2ba1662ce710f6530f5b0a6656f1c32b58"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:319eb2a8d0888fa6f1d9177705f341bc9455a2c8aca130016e52c7fe8d6c37a3"}, + {file = "regex-2021.7.6-cp39-cp39-win32.whl", hash = "sha256:eaf58b9e30e0e546cdc3ac06cf9165a1ca5b3de8221e9df679416ca667972035"}, + {file = "regex-2021.7.6-cp39-cp39-win_amd64.whl", hash = "sha256:4c9c3155fe74269f61e27617529b7f09552fbb12e44b1189cebbdb24294e6e1c"}, + {file = "regex-2021.7.6.tar.gz", hash = "sha256:8394e266005f2d8c6f0bc6780001f7afa3ef81a7a2111fa35058ded6fce79e4d"}, +] +rich = [ + {file = "rich-10.5.0-py3-none-any.whl", hash = "sha256:d36d4dddbb6cb87cdcb2c02f8ffd7836e1b136e3ba45d4b5a4da057f3b5e7798"}, + {file = "rich-10.5.0.tar.gz", hash = "sha256:f8a16484b3d70708bdafd04f659f9ca0e2c0129b33a343c10c734838d361777f"}, ] secretstorage = [ {file = "SecretStorage-3.3.1-py3-none-any.whl", hash = "sha256:422d82c36172d88d6a0ed5afdec956514b189ddbfb72fefab0c8a1cee4eaf71f"}, {file = "SecretStorage-3.3.1.tar.gz", hash = "sha256:fd666c51a6bf200643495a04abb261f83229dcb6fd8472ec393df7ffc8b6f195"}, ] +setuptools = [ + {file = "setuptools-57.1.0-py3-none-any.whl", hash = "sha256:ddae4c1b9220daf1e32ba9d4e3714df6019c5b583755559be84ff8199f7e1fe3"}, + {file = "setuptools-57.1.0.tar.gz", hash = "sha256:cfca9c97e7eebbc8abe18d5e5e962a08dcad55bb63afddd82d681de4d22a597b"}, +] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] -termcolor = [ - {file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"}, -] textwrap3 = [ {file = "textwrap3-0.9.2-py2.py3-none-any.whl", hash = "sha256:bf5f4c40faf2a9ff00a9e0791fed5da7415481054cef45bb4a3cfb1f69044ae0"}, {file = "textwrap3-0.9.2.zip", hash = "sha256:5008eeebdb236f6303dcd68f18b856d355f6197511d952ba74bc75e40e0c3414"}, @@ -1344,14 +1364,6 @@ wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, ] -xmltodict = [ - {file = "xmltodict-0.12.0-py2.py3-none-any.whl", hash = "sha256:8bbcb45cc982f48b2ca8fe7e7827c5d792f217ecf1792626f808bf41c3b86051"}, - {file = "xmltodict-0.12.0.tar.gz", hash = "sha256:50d8c638ed7ecb88d90561beedbf720c9b4e851a9fa6c47ebd64e99d166d8a21"}, -] -yq = [ - {file = "yq-2.12.2-py2.py3-none-any.whl", hash = "sha256:9fdf4487a6dbf985ca1d357ec93f926d982813e8e896e8892bae95162b6defe3"}, - {file = "yq-2.12.2.tar.gz", hash = "sha256:2f156d0724b61487ac8752ed4eaa702a5737b804d5afa46fa55866951cd106d2"}, -] zipp = [ {file = "zipp-3.5.0-py3-none-any.whl", hash = "sha256:957cfda87797e389580cb8b9e3870841ca991e2125350677b2ca83a0e99390a3"}, {file = "zipp-3.5.0.tar.gz", hash = "sha256:f5812b1e007e48cff63449a5e9f4e7ebea716b4111f9c4f9a645f91d579bf0c4"}, diff --git a/pyproject.toml b/pyproject.toml index 36bc3d13..3f5c5644 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,7 @@ classifiers = [ "Funding" = "https://opencollective.com/jrnl" [tool.poetry.dependencies] -python = ">=3.7.0, <3.10" +python = ">=3.7.0, <3.11" ansiwrap = "^0.8.4" asteval = "^0.9" @@ -43,17 +43,28 @@ pyyaml = ">=5.1" pytz = ">=2020" # https://pythonhosted.org/pytz/#issues-limitations tzlocal = ">2.0, <3.0" # https://github.com/regebro/tzlocal/blob/master/CHANGES.txt +# Minimal deps required for testing +# I don't like repeating deps here, but +# there's no other way to do this yet until poetry v1.2 releases +# see: https://github.com/python-poetry/poetry/issues/1644 +behave = { version = "^1.2" , optional = true } +pytest = { version = ">=6.2" , optional = true } +pytest-bdd = { version = ">=4.0.1" , optional = true } +toml = { version = ">=0.10" , optional = true } + [tool.poetry.dev-dependencies] behave = "^1.2" -mkdocs = "^1.0" -black = {version = "^21.5b2",allow-prereleases = true} +mkdocs = ">=1.0" +black = { version = ">=21.5b2", allow-prereleases = true } toml = ">=0.10" pytest = ">=6.2" -pytest-bdd = "^4.0.1" -yq = ">=2.11" -ipdb = ">=0.13" -pytest-clarity = "^0.3.0-alpha.0" -pyproject-flake8 = "^0.0.1-alpha.2" +pytest-bdd = ">=4.0.1" +ipdb = "*" +pytest-clarity = "*" +pyproject-flake8 = "*" + +[tool.poetry.extras] +testing = [ "behave", "pytest", "pytest-bdd", "toml" ] [tool.poetry.scripts] jrnl = 'jrnl.cli:cli' From 9bd395007fa38cbf82e2a6d6b41734cbcda40eeb Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 10 Jul 2021 19:14:56 +0000 Subject: [PATCH 159/215] Update changelog [ci skip] --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7700ab4..f157f10c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,15 @@ [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.1...HEAD) +**Implemented enhancements:** + +- Python 3.10 support [\#1270](https://github.com/jrnl-org/jrnl/issues/1270) + **Build:** - Move test suite entirely to Pytest \(replace Behave\) [\#1192](https://github.com/jrnl-org/jrnl/issues/1192) - Remove useless shebangs and executable permissions [\#1283](https://github.com/jrnl-org/jrnl/pull/1283) ([musicinmybrain](https://github.com/musicinmybrain)) +- Add Python 3.10 support [\#1271](https://github.com/jrnl-org/jrnl/pull/1271) ([micahellison](https://github.com/micahellison)) - Remove `--version` from brew release workflow [\#1233](https://github.com/jrnl-org/jrnl/pull/1233) ([wren](https://github.com/wren)) - Move test suite to Pytest \(replace Behave\) [\#1193](https://github.com/jrnl-org/jrnl/pull/1193) ([wren](https://github.com/wren)) From e771c9da8198b8979186c8ccd353b26802bb6a2a Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 10 Jul 2021 13:53:00 -0700 Subject: [PATCH 160/215] Update lock file from poetry stable version (#1298) --- poetry.lock | 104 +++++++++++++++++++++++----------------------------- 1 file changed, 45 insertions(+), 59 deletions(-) diff --git a/poetry.lock b/poetry.lock index 172a2533..54f35f7a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -106,7 +106,7 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "cffi" -version = "1.14.5" +version = "1.14.6" description = "Foreign Function Interface for Python calling C code." category = "main" optional = false @@ -245,7 +245,6 @@ python-versions = ">=2.7" [package.dependencies] decorator = {version = "*", markers = "python_version > \"3.6\""} ipython = {version = ">=7.17.0", markers = "python_version > \"3.6\""} -setuptools = "*" toml = {version = ">=0.10.2", markers = "python_version > \"3.6\""} [[package]] @@ -267,7 +266,6 @@ pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} pickleshare = "*" prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" pygments = "*" -setuptools = ">=18.5" traitlets = ">=4.2" [package.extras] @@ -306,7 +304,7 @@ testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<6.0.0)"] [[package]] name = "jeepney" -version = "0.6.0" +version = "0.7.0" description = "Low-level, pure Python DBus protocol wrapper." category = "main" optional = false @@ -314,6 +312,7 @@ python-versions = ">=3.6" [package.extras] test = ["pytest", "pytest-trio", "pytest-asyncio", "testpath", "trio"] +trio = ["trio", "async-generator"] [[package]] name = "jinja2" @@ -767,18 +766,6 @@ python-versions = ">=3.6" cryptography = ">=2.0" jeepney = ">=0.6" -[[package]] -name = "setuptools" -version = "57.1.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "pygments-github-lexers (==0.0.5)", "sphinx-inline-tabs", "sphinxcontrib-towncrier"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "mock", "flake8-2020", "virtualenv (>=13.0.0)", "pytest-virtualenv (>=1.2.7)", "wheel", "paver", "pip (>=19.1)", "jaraco.envs", "pytest-xdist", "sphinx", "jaraco.path (>=3.2.0)", "pytest-black (>=0.3.7)", "pytest-mypy"] - [[package]] name = "six" version = "1.16.0" @@ -920,43 +907,46 @@ black = [ {file = "black-21.6b0.tar.gz", hash = "sha256:dc132348a88d103016726fe360cb9ede02cecf99b76e3660ce6c596be132ce04"}, ] cffi = [ - {file = "cffi-1.14.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:bb89f306e5da99f4d922728ddcd6f7fcebb3241fc40edebcb7284d7514741991"}, - {file = "cffi-1.14.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:34eff4b97f3d982fb93e2831e6750127d1355a923ebaeeb565407b3d2f8d41a1"}, - {file = "cffi-1.14.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:99cd03ae7988a93dd00bcd9d0b75e1f6c426063d6f03d2f90b89e29b25b82dfa"}, - {file = "cffi-1.14.5-cp27-cp27m-win32.whl", hash = "sha256:65fa59693c62cf06e45ddbb822165394a288edce9e276647f0046e1ec26920f3"}, - {file = "cffi-1.14.5-cp27-cp27m-win_amd64.whl", hash = "sha256:51182f8927c5af975fece87b1b369f722c570fe169f9880764b1ee3bca8347b5"}, - {file = "cffi-1.14.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:43e0b9d9e2c9e5d152946b9c5fe062c151614b262fda2e7b201204de0b99e482"}, - {file = "cffi-1.14.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:cbde590d4faaa07c72bf979734738f328d239913ba3e043b1e98fe9a39f8b2b6"}, - {file = "cffi-1.14.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:5de7970188bb46b7bf9858eb6890aad302577a5f6f75091fd7cdd3ef13ef3045"}, - {file = "cffi-1.14.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:a465da611f6fa124963b91bf432d960a555563efe4ed1cc403ba5077b15370aa"}, - {file = "cffi-1.14.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:d42b11d692e11b6634f7613ad8df5d6d5f8875f5d48939520d351007b3c13406"}, - {file = "cffi-1.14.5-cp35-cp35m-win32.whl", hash = "sha256:72d8d3ef52c208ee1c7b2e341f7d71c6fd3157138abf1a95166e6165dd5d4369"}, - {file = "cffi-1.14.5-cp35-cp35m-win_amd64.whl", hash = "sha256:29314480e958fd8aab22e4a58b355b629c59bf5f2ac2492b61e3dc06d8c7a315"}, - {file = "cffi-1.14.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3d3dd4c9e559eb172ecf00a2a7517e97d1e96de2a5e610bd9b68cea3925b4892"}, - {file = "cffi-1.14.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:48e1c69bbacfc3d932221851b39d49e81567a4d4aac3b21258d9c24578280058"}, - {file = "cffi-1.14.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:69e395c24fc60aad6bb4fa7e583698ea6cc684648e1ffb7fe85e3c1ca131a7d5"}, - {file = "cffi-1.14.5-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:9e93e79c2551ff263400e1e4be085a1210e12073a31c2011dbbda14bda0c6132"}, - {file = "cffi-1.14.5-cp36-cp36m-win32.whl", hash = "sha256:58e3f59d583d413809d60779492342801d6e82fefb89c86a38e040c16883be53"}, - {file = "cffi-1.14.5-cp36-cp36m-win_amd64.whl", hash = "sha256:005a36f41773e148deac64b08f233873a4d0c18b053d37da83f6af4d9087b813"}, - {file = "cffi-1.14.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2894f2df484ff56d717bead0a5c2abb6b9d2bf26d6960c4604d5c48bbc30ee73"}, - {file = "cffi-1.14.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0857f0ae312d855239a55c81ef453ee8fd24136eaba8e87a2eceba644c0d4c06"}, - {file = "cffi-1.14.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:cd2868886d547469123fadc46eac7ea5253ea7fcb139f12e1dfc2bbd406427d1"}, - {file = "cffi-1.14.5-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:35f27e6eb43380fa080dccf676dece30bef72e4a67617ffda586641cd4508d49"}, - {file = "cffi-1.14.5-cp37-cp37m-win32.whl", hash = "sha256:9ff227395193126d82e60319a673a037d5de84633f11279e336f9c0f189ecc62"}, - {file = "cffi-1.14.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9cf8022fb8d07a97c178b02327b284521c7708d7c71a9c9c355c178ac4bbd3d4"}, - {file = "cffi-1.14.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8b198cec6c72df5289c05b05b8b0969819783f9418e0409865dac47288d2a053"}, - {file = "cffi-1.14.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:ad17025d226ee5beec591b52800c11680fca3df50b8b29fe51d882576e039ee0"}, - {file = "cffi-1.14.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6c97d7350133666fbb5cf4abdc1178c812cb205dc6f41d174a7b0f18fb93337e"}, - {file = "cffi-1.14.5-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8ae6299f6c68de06f136f1f9e69458eae58f1dacf10af5c17353eae03aa0d827"}, - {file = "cffi-1.14.5-cp38-cp38-win32.whl", hash = "sha256:b85eb46a81787c50650f2392b9b4ef23e1f126313b9e0e9013b35c15e4288e2e"}, - {file = "cffi-1.14.5-cp38-cp38-win_amd64.whl", hash = "sha256:1f436816fc868b098b0d63b8920de7d208c90a67212546d02f84fe78a9c26396"}, - {file = "cffi-1.14.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1071534bbbf8cbb31b498d5d9db0f274f2f7a865adca4ae429e147ba40f73dea"}, - {file = "cffi-1.14.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9de2e279153a443c656f2defd67769e6d1e4163952b3c622dcea5b08a6405322"}, - {file = "cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6e4714cc64f474e4d6e37cfff31a814b509a35cb17de4fb1999907575684479c"}, - {file = "cffi-1.14.5-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:158d0d15119b4b7ff6b926536763dc0714313aa59e320ddf787502c70c4d4bee"}, - {file = "cffi-1.14.5-cp39-cp39-win32.whl", hash = "sha256:afb29c1ba2e5a3736f1c301d9d0abe3ec8b86957d04ddfa9d7a6a42b9367e396"}, - {file = "cffi-1.14.5-cp39-cp39-win_amd64.whl", hash = "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d"}, - {file = "cffi-1.14.5.tar.gz", hash = "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"}, + {file = "cffi-1.14.6-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:22b9c3c320171c108e903d61a3723b51e37aaa8c81255b5e7ce102775bd01e2c"}, + {file = "cffi-1.14.6-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:f0c5d1acbfca6ebdd6b1e3eded8d261affb6ddcf2186205518f1428b8569bb99"}, + {file = "cffi-1.14.6-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:99f27fefe34c37ba9875f224a8f36e31d744d8083e00f520f133cab79ad5e819"}, + {file = "cffi-1.14.6-cp27-cp27m-win32.whl", hash = "sha256:55af55e32ae468e9946f741a5d51f9896da6b9bf0bbdd326843fec05c730eb20"}, + {file = "cffi-1.14.6-cp27-cp27m-win_amd64.whl", hash = "sha256:7bcac9a2b4fdbed2c16fa5681356d7121ecabf041f18d97ed5b8e0dd38a80224"}, + {file = "cffi-1.14.6-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ed38b924ce794e505647f7c331b22a693bee1538fdf46b0222c4717b42f744e7"}, + {file = "cffi-1.14.6-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e22dcb48709fc51a7b58a927391b23ab37eb3737a98ac4338e2448bef8559b33"}, + {file = "cffi-1.14.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e8c6a99be100371dbb046880e7a282152aa5d6127ae01783e37662ef73850d8f"}, + {file = "cffi-1.14.6-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:19ca0dbdeda3b2615421d54bef8985f72af6e0c47082a8d26122adac81a95872"}, + {file = "cffi-1.14.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d950695ae4381ecd856bcaf2b1e866720e4ab9a1498cba61c602e56630ca7195"}, + {file = "cffi-1.14.6-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9dc245e3ac69c92ee4c167fbdd7428ec1956d4e754223124991ef29eb57a09d"}, + {file = "cffi-1.14.6-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8661b2ce9694ca01c529bfa204dbb144b275a31685a075ce123f12331be790b"}, + {file = "cffi-1.14.6-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b315d709717a99f4b27b59b021e6207c64620790ca3e0bde636a6c7f14618abb"}, + {file = "cffi-1.14.6-cp36-cp36m-win32.whl", hash = "sha256:80b06212075346b5546b0417b9f2bf467fea3bfe7352f781ffc05a8ab24ba14a"}, + {file = "cffi-1.14.6-cp36-cp36m-win_amd64.whl", hash = "sha256:a9da7010cec5a12193d1af9872a00888f396aba3dc79186604a09ea3ee7c029e"}, + {file = "cffi-1.14.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4373612d59c404baeb7cbd788a18b2b2a8331abcc84c3ba40051fcd18b17a4d5"}, + {file = "cffi-1.14.6-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f10afb1004f102c7868ebfe91c28f4a712227fe4cb24974350ace1f90e1febbf"}, + {file = "cffi-1.14.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:fd4305f86f53dfd8cd3522269ed7fc34856a8ee3709a5e28b2836b2db9d4cd69"}, + {file = "cffi-1.14.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d6169cb3c6c2ad50db5b868db6491a790300ade1ed5d1da29289d73bbe40b56"}, + {file = "cffi-1.14.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d4b68e216fc65e9fe4f524c177b54964af043dde734807586cf5435af84045c"}, + {file = "cffi-1.14.6-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33791e8a2dc2953f28b8d8d300dde42dd929ac28f974c4b4c6272cb2955cb762"}, + {file = "cffi-1.14.6-cp37-cp37m-win32.whl", hash = "sha256:0c0591bee64e438883b0c92a7bed78f6290d40bf02e54c5bf0978eaf36061771"}, + {file = "cffi-1.14.6-cp37-cp37m-win_amd64.whl", hash = "sha256:8eb687582ed7cd8c4bdbff3df6c0da443eb89c3c72e6e5dcdd9c81729712791a"}, + {file = "cffi-1.14.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ba6f2b3f452e150945d58f4badd92310449876c4c954836cfb1803bdd7b422f0"}, + {file = "cffi-1.14.6-cp38-cp38-manylinux1_i686.whl", hash = "sha256:64fda793737bc4037521d4899be780534b9aea552eb673b9833b01f945904c2e"}, + {file = "cffi-1.14.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:9f3e33c28cd39d1b655ed1ba7247133b6f7fc16fa16887b120c0c670e35ce346"}, + {file = "cffi-1.14.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26bb2549b72708c833f5abe62b756176022a7b9a7f689b571e74c8478ead51dc"}, + {file = "cffi-1.14.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb687a11f0a7a1839719edd80f41e459cc5366857ecbed383ff376c4e3cc6afd"}, + {file = "cffi-1.14.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d2ad4d668a5c0645d281dcd17aff2be3212bc109b33814bbb15c4939f44181cc"}, + {file = "cffi-1.14.6-cp38-cp38-win32.whl", hash = "sha256:487d63e1454627c8e47dd230025780e91869cfba4c753a74fda196a1f6ad6548"}, + {file = "cffi-1.14.6-cp38-cp38-win_amd64.whl", hash = "sha256:c33d18eb6e6bc36f09d793c0dc58b0211fccc6ae5149b808da4a62660678b156"}, + {file = "cffi-1.14.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:06c54a68935738d206570b20da5ef2b6b6d92b38ef3ec45c5422c0ebaf338d4d"}, + {file = "cffi-1.14.6-cp39-cp39-manylinux1_i686.whl", hash = "sha256:f174135f5609428cc6e1b9090f9268f5c8935fddb1b25ccb8255a2d50de6789e"}, + {file = "cffi-1.14.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f3ebe6e73c319340830a9b2825d32eb6d8475c1dac020b4f0aa774ee3b898d1c"}, + {file = "cffi-1.14.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c8d896becff2fa653dc4438b54a5a25a971d1f4110b32bd3068db3722c80202"}, + {file = "cffi-1.14.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4922cd707b25e623b902c86188aca466d3620892db76c0bdd7b99a3d5e61d35f"}, + {file = "cffi-1.14.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c9e005e9bd57bc987764c32a1bee4364c44fdc11a3cc20a40b93b444984f2b87"}, + {file = "cffi-1.14.6-cp39-cp39-win32.whl", hash = "sha256:eb9e2a346c5238a30a746893f23a9535e700f8192a68c07c0258e7ece6ff3728"}, + {file = "cffi-1.14.6-cp39-cp39-win_amd64.whl", hash = "sha256:818014c754cd3dba7229c0f5884396264d51ffb87ec86e927ef0be140bfdb0d2"}, + {file = "cffi-1.14.6.tar.gz", hash = "sha256:c9a875ce9d7fe32887784274dd533c57909b7b1dcadcc128a2ac21331a9765dd"}, ] click = [ {file = "click-8.0.1-py3-none-any.whl", hash = "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"}, @@ -1022,8 +1012,8 @@ jedi = [ {file = "jedi-0.18.0.tar.gz", hash = "sha256:92550a404bad8afed881a137ec9a461fed49eca661414be45059329614ed0707"}, ] jeepney = [ - {file = "jeepney-0.6.0-py3-none-any.whl", hash = "sha256:aec56c0eb1691a841795111e184e13cad504f7703b9a64f63020816afa79a8ae"}, - {file = "jeepney-0.6.0.tar.gz", hash = "sha256:7d59b6622675ca9e993a6bd38de845051d315f8b0c72cca3aef733a20b648657"}, + {file = "jeepney-0.7.0-py3-none-any.whl", hash = "sha256:71335e7a4e93817982f473f3507bffc2eff7a544119ab9b73e089c8ba1409ba3"}, + {file = "jeepney-0.7.0.tar.gz", hash = "sha256:1237cd64c8f7ac3aa4b3f332c4d0fb4a8216f39eaa662ec904302d4d77de5a54"}, ] jinja2 = [ {file = "Jinja2-3.0.1-py3-none-any.whl", hash = "sha256:1f06f2da51e7b56b8f238affdd6b4e2c61e39598a378cc49345bc1bd42a978a4"}, @@ -1276,10 +1266,6 @@ secretstorage = [ {file = "SecretStorage-3.3.1-py3-none-any.whl", hash = "sha256:422d82c36172d88d6a0ed5afdec956514b189ddbfb72fefab0c8a1cee4eaf71f"}, {file = "SecretStorage-3.3.1.tar.gz", hash = "sha256:fd666c51a6bf200643495a04abb261f83229dcb6fd8472ec393df7ffc8b6f195"}, ] -setuptools = [ - {file = "setuptools-57.1.0-py3-none-any.whl", hash = "sha256:ddae4c1b9220daf1e32ba9d4e3714df6019c5b583755559be84ff8199f7e1fe3"}, - {file = "setuptools-57.1.0.tar.gz", hash = "sha256:cfca9c97e7eebbc8abe18d5e5e962a08dcad55bb63afddd82d681de4d22a597b"}, -] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, From 7b72b24ee254d3043c410fbd31779c0d10400630 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 17 Jul 2021 12:01:59 -0700 Subject: [PATCH 161/215] Add first draft of security.md (#1299) --- SECURITY.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..c239b957 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,7 @@ +# Security + +If you've discovered a potential security issue in jrnl, please contact the maintainers at [jrnl-sh@googlegroups.com](mailto:jrnl-sh@googlegroups.com). + +You can also feel free to [open an issue](https://github.com/jrnl-org/jrnl/issues/new/choose) (but please don't disclose the vulnerability) in case the email goes to spam. + +You can find [known privacy and security issues in our documentation](https://jrnl.sh/en/stable/privacy-and-security/). From b896c85bf0e2fe3d8131bca55456e8393f53361e Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 17 Jul 2021 19:03:29 +0000 Subject: [PATCH 162/215] Update changelog [ci skip] --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f157f10c..8a14e274 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ - Remove `--version` from brew release workflow [\#1233](https://github.com/jrnl-org/jrnl/pull/1233) ([wren](https://github.com/wren)) - Move test suite to Pytest \(replace Behave\) [\#1193](https://github.com/jrnl-org/jrnl/pull/1193) ([wren](https://github.com/wren)) +**Documentation:** + +- Create security.md [\#1284](https://github.com/jrnl-org/jrnl/issues/1284) + **Packaging:** - Bump black from 21.5b1 to 21.5b2 [\#1254](https://github.com/jrnl-org/jrnl/pull/1254) ([dependabot[bot]](https://github.com/apps/dependabot)) From 52c0a0ebf31166b7ed80a753ddceebbeb99392e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 17 Jul 2021 12:13:19 -0700 Subject: [PATCH 163/215] Bump python-dateutil from 2.8.1 to 2.8.2 (#1302) Bumps [python-dateutil](https://github.com/dateutil/dateutil) from 2.8.1 to 2.8.2. - [Release notes](https://github.com/dateutil/dateutil/releases) - [Changelog](https://github.com/dateutil/dateutil/blob/master/NEWS) - [Commits](https://github.com/dateutil/dateutil/compare/2.8.1...2.8.2) --- updated-dependencies: - dependency-name: python-dateutil dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 54f35f7a..04fe06c3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -677,7 +677,7 @@ rich = ">=8.0.0" [[package]] name = "python-dateutil" -version = "2.8.1" +version = "2.8.2" description = "Extensions to the standard Python datetime module" category = "main" optional = false @@ -914,6 +914,11 @@ cffi = [ {file = "cffi-1.14.6-cp27-cp27m-win_amd64.whl", hash = "sha256:7bcac9a2b4fdbed2c16fa5681356d7121ecabf041f18d97ed5b8e0dd38a80224"}, {file = "cffi-1.14.6-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ed38b924ce794e505647f7c331b22a693bee1538fdf46b0222c4717b42f744e7"}, {file = "cffi-1.14.6-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e22dcb48709fc51a7b58a927391b23ab37eb3737a98ac4338e2448bef8559b33"}, + {file = "cffi-1.14.6-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:aedb15f0a5a5949ecb129a82b72b19df97bbbca024081ed2ef88bd5c0a610534"}, + {file = "cffi-1.14.6-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:48916e459c54c4a70e52745639f1db524542140433599e13911b2f329834276a"}, + {file = "cffi-1.14.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f627688813d0a4140153ff532537fbe4afea5a3dffce1f9deb7f91f848a832b5"}, + {file = "cffi-1.14.6-cp35-cp35m-win32.whl", hash = "sha256:f0010c6f9d1a4011e429109fda55a225921e3206e7f62a0c22a35344bfd13cca"}, + {file = "cffi-1.14.6-cp35-cp35m-win_amd64.whl", hash = "sha256:57e555a9feb4a8460415f1aac331a2dc833b1115284f7ded7278b54afc5bd218"}, {file = "cffi-1.14.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e8c6a99be100371dbb046880e7a282152aa5d6127ae01783e37662ef73850d8f"}, {file = "cffi-1.14.6-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:19ca0dbdeda3b2615421d54bef8985f72af6e0c47082a8d26122adac81a95872"}, {file = "cffi-1.14.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d950695ae4381ecd856bcaf2b1e866720e4ab9a1498cba61c602e56630ca7195"}, @@ -1024,6 +1029,7 @@ keyring = [ {file = "keyring-23.0.1.tar.gz", hash = "sha256:045703609dd3fccfcdb27da201684278823b72af515aedec1a8515719a038cb8"}, ] mako = [ + {file = "Mako-1.1.4-py2.py3-none-any.whl", hash = "sha256:aea166356da44b9b830c8023cd9b557fa856bd8b4035d6de771ca027dfc5cc6e"}, {file = "Mako-1.1.4.tar.gz", hash = "sha256:17831f0b7087c313c0ffae2bcbbd3c1d5ba9eeac9c38f2eb7b50e8c99fe9d5ab"}, ] markdown = [ @@ -1173,8 +1179,8 @@ pytest-clarity = [ {file = "pytest-clarity-1.0.1.tar.gz", hash = "sha256:505fe345fad4fe11c6a4187fe683f2c7c52c077caa1e135f3e483fe112db7772"}, ] python-dateutil = [ - {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, - {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] pytz = [ {file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"}, @@ -1195,18 +1201,26 @@ pyyaml = [ {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, From 3e95a46bd219cdbcddb5c4451400bc9dc72afe87 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 17 Jul 2021 19:15:00 +0000 Subject: [PATCH 164/215] Update changelog [ci skip] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a14e274..0bbdb22b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ **Packaging:** +- Bump python-dateutil from 2.8.1 to 2.8.2 [\#1302](https://github.com/jrnl-org/jrnl/pull/1302) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump black from 21.5b1 to 21.5b2 [\#1254](https://github.com/jrnl-org/jrnl/pull/1254) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump black from 21.5b0 to 21.5b1 [\#1244](https://github.com/jrnl-org/jrnl/pull/1244) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump black from 20.8b1 to 21.5b0 [\#1241](https://github.com/jrnl-org/jrnl/pull/1241) ([dependabot[bot]](https://github.com/apps/dependabot)) From 31f782e333baf0fc39b19e45aa2708349325d2d6 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 17 Jul 2021 13:22:01 -0700 Subject: [PATCH 165/215] Add documentation about saved passwords in Windows (#1301) * Add note about saved passwords * Add missing yq dep back in to allow xq to run in mkdocs CI pipeline --- docs/privacy-and-security.md | 12 ++++++ poetry.lock | 79 ++++++++++++++++++++++++++++++++---- pyproject.toml | 1 + 3 files changed, 84 insertions(+), 8 deletions(-) diff --git a/docs/privacy-and-security.md b/docs/privacy-and-security.md index 39f4863c..c2996d25 100644 --- a/docs/privacy-and-security.md +++ b/docs/privacy-and-security.md @@ -86,6 +86,18 @@ you have a journal, where that journal file is, and when you last edited it. With a sufficient power imbalance, someone may be able to force you to unencrypt it through non-technical means. +## Saved Passwords + +When creating an encrypted journal, you'll be prompted as to whether or not you +want to "store the password in your keychain." This keychain is accessed using +the [Python keyring library](https://pypi.org/project/keyring/), which has different +behavior depending on your operating system. + +In Windows, the keychain is the Windows Credential Manager (WCM), which can't be locked +and can be accessed by any other application running under your username. If this is +a concern for you, you may not want to store your password. + + ## Notice any other risks? Please let the maintainers know by [filing an issue on GitHub](https://github.com/jrnl-org/jrnl/issues). diff --git a/poetry.lock b/poetry.lock index 04fe06c3..94b251d3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -25,6 +25,20 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "argcomplete" +version = "1.12.3" +description = "Bash tab completion for argparse" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +importlib-metadata = {version = ">=0.23,<5", markers = "python_version == \"3.7\""} + +[package.extras] +test = ["coverage", "flake8", "pexpect", "wheel"] + [[package]] name = "asteval" version = "0.9.25" @@ -82,7 +96,7 @@ docs = ["sphinx (>=1.6)", "sphinx-bootstrap-theme (>=0.6)"] [[package]] name = "black" -version = "21.6b0" +version = "21.7b0" description = "The uncompromising code formatter." category = "dev" optional = false @@ -94,7 +108,7 @@ click = ">=7.1.2" mypy-extensions = ">=0.4.3" pathspec = ">=0.8.1,<1" regex = ">=2020.1.8" -toml = ">=0.10.1" +tomli = ">=0.2.6,<2.0.0" typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\""} typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} @@ -739,7 +753,7 @@ python-versions = "*" [[package]] name = "rich" -version = "10.5.0" +version = "10.6.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" category = "dev" optional = false @@ -790,6 +804,14 @@ category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "tomli" +version = "1.0.4" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.6" + [[package]] name = "traitlets" version = "5.0.5" @@ -850,6 +872,31 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "xmltodict" +version = "0.12.0" +description = "Makes working with XML feel like you are working with JSON" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "yq" +version = "2.12.2" +description = "Command-line YAML/XML processor - jq wrapper for YAML/XML documents" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +argcomplete = ">=1.8.1" +PyYAML = ">=3.11" +toml = ">=0.10.0" +xmltodict = ">=0.11.0" + +[package.extras] +test = ["coverage", "flake8", "wheel"] + [[package]] name = "zipp" version = "3.5.0" @@ -868,7 +915,7 @@ testing = ["behave", "pytest", "pytest-bdd", "toml"] [metadata] lock-version = "1.1" python-versions = ">=3.7.0, <3.11" -content-hash = "8549770f6a13b58f3baf9b434b326fc6bfc69eaccd604efcce110744fabdac64" +content-hash = "c4f943f3dbd96f5aab8ad0ef2f3d3f6a7096dc75ea7d3e449949695d340208fb" [metadata.files] ansiwrap = [ @@ -883,6 +930,10 @@ appnope = [ {file = "appnope-0.1.2-py2.py3-none-any.whl", hash = "sha256:93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442"}, {file = "appnope-0.1.2.tar.gz", hash = "sha256:dd83cd4b5b460958838f6eb3000c660b1f9caf2a5b1de4264e941512f603258a"}, ] +argcomplete = [ + {file = "argcomplete-1.12.3-py2.py3-none-any.whl", hash = "sha256:291f0beca7fd49ce285d2f10e4c1c77e9460cf823eef2de54df0c0fec88b0d81"}, + {file = "argcomplete-1.12.3.tar.gz", hash = "sha256:2c7dbffd8c045ea534921e63b0be6fe65e88599990d8dc408ac8c542b72a5445"}, +] asteval = [ {file = "asteval-0.9.25.tar.gz", hash = "sha256:bea22b7d8fa16bcba95ebc72052ae5d8ca97114c9959bb47f8b8eebf30e4342f"}, ] @@ -903,8 +954,8 @@ behave = [ {file = "behave-1.2.6.tar.gz", hash = "sha256:b9662327aa53294c1351b0a9c369093ccec1d21026f050c3bd9b3e5cccf81a86"}, ] black = [ - {file = "black-21.6b0-py3-none-any.whl", hash = "sha256:dfb8c5a069012b2ab1e972e7b908f5fb42b6bbabcba0a788b86dc05067c7d9c7"}, - {file = "black-21.6b0.tar.gz", hash = "sha256:dc132348a88d103016726fe360cb9ede02cecf99b76e3660ce6c596be132ce04"}, + {file = "black-21.7b0-py3-none-any.whl", hash = "sha256:1c7aa6ada8ee864db745b22790a32f94b2795c253a75d6d9b5e439ff10d23116"}, + {file = "black-21.7b0.tar.gz", hash = "sha256:c8373c6491de9362e39271630b65b964607bc5c79c83783547d76c839b3aa219"}, ] cffi = [ {file = "cffi-1.14.6-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:22b9c3c320171c108e903d61a3723b51e37aaa8c81255b5e7ce102775bd01e2c"}, @@ -1273,8 +1324,8 @@ regex = [ {file = "regex-2021.7.6.tar.gz", hash = "sha256:8394e266005f2d8c6f0bc6780001f7afa3ef81a7a2111fa35058ded6fce79e4d"}, ] rich = [ - {file = "rich-10.5.0-py3-none-any.whl", hash = "sha256:d36d4dddbb6cb87cdcb2c02f8ffd7836e1b136e3ba45d4b5a4da057f3b5e7798"}, - {file = "rich-10.5.0.tar.gz", hash = "sha256:f8a16484b3d70708bdafd04f659f9ca0e2c0129b33a343c10c734838d361777f"}, + {file = "rich-10.6.0-py3-none-any.whl", hash = "sha256:d3f72827cd5df13b2ef7f1a97f81ec65548d4fdeb92cef653234f227580bbb2a"}, + {file = "rich-10.6.0.tar.gz", hash = "sha256:128261b3e2419a4ef9c97066ccc2abbfb49fa7c5e89c3fe4056d00aa5e9c1e65"}, ] secretstorage = [ {file = "SecretStorage-3.3.1-py3-none-any.whl", hash = "sha256:422d82c36172d88d6a0ed5afdec956514b189ddbfb72fefab0c8a1cee4eaf71f"}, @@ -1292,6 +1343,10 @@ toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] +tomli = [ + {file = "tomli-1.0.4-py3-none-any.whl", hash = "sha256:0713b16ff91df8638a6a694e295c8159ab35ba93e3424a626dd5226d386057be"}, + {file = "tomli-1.0.4.tar.gz", hash = "sha256:be670d0d8d7570fd0ea0113bd7bb1ba3ac6706b4de062cc4c952769355c9c268"}, +] traitlets = [ {file = "traitlets-5.0.5-py3-none-any.whl", hash = "sha256:69ff3f9d5351f31a7ad80443c2674b7099df13cc41fc5fa6e2f6d3b0330b0426"}, {file = "traitlets-5.0.5.tar.gz", hash = "sha256:178f4ce988f69189f7e523337a3e11d91c786ded9360174a3d9ca83e79bc5396"}, @@ -1364,6 +1419,14 @@ wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, ] +xmltodict = [ + {file = "xmltodict-0.12.0-py2.py3-none-any.whl", hash = "sha256:8bbcb45cc982f48b2ca8fe7e7827c5d792f217ecf1792626f808bf41c3b86051"}, + {file = "xmltodict-0.12.0.tar.gz", hash = "sha256:50d8c638ed7ecb88d90561beedbf720c9b4e851a9fa6c47ebd64e99d166d8a21"}, +] +yq = [ + {file = "yq-2.12.2-py2.py3-none-any.whl", hash = "sha256:9fdf4487a6dbf985ca1d357ec93f926d982813e8e896e8892bae95162b6defe3"}, + {file = "yq-2.12.2.tar.gz", hash = "sha256:2f156d0724b61487ac8752ed4eaa702a5737b804d5afa46fa55866951cd106d2"}, +] zipp = [ {file = "zipp-3.5.0-py3-none-any.whl", hash = "sha256:957cfda87797e389580cb8b9e3870841ca991e2125350677b2ca83a0e99390a3"}, {file = "zipp-3.5.0.tar.gz", hash = "sha256:f5812b1e007e48cff63449a5e9f4e7ebea716b4111f9c4f9a645f91d579bf0c4"}, diff --git a/pyproject.toml b/pyproject.toml index 3f5c5644..5c6d5cbd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,6 +62,7 @@ pytest-bdd = ">=4.0.1" ipdb = "*" pytest-clarity = "*" pyproject-flake8 = "*" +yq = "*" [tool.poetry.extras] testing = [ "behave", "pytest", "pytest-bdd", "toml" ] From cef3a98b4e3c924613aa6f1eb17df9de0e3be926 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 17 Jul 2021 20:23:48 +0000 Subject: [PATCH 166/215] Update changelog [ci skip] --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bbdb22b..b43053e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ **Documentation:** - Create security.md [\#1284](https://github.com/jrnl-org/jrnl/issues/1284) +- Document keyring security concerns on Windows, Mac [\#1142](https://github.com/jrnl-org/jrnl/issues/1142) +- Add documentation about saved passwords in Windows [\#1301](https://github.com/jrnl-org/jrnl/pull/1301) ([micahellison](https://github.com/micahellison)) **Packaging:** From f158d7f266d33c739eb1bed27d6761f258246b54 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 17 Jul 2021 22:16:08 +0000 Subject: [PATCH 167/215] Increment version to v2.8.2-beta --- jrnl/__version__.py | 2 +- pyproject.toml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/jrnl/__version__.py b/jrnl/__version__.py index 51977ba3..62fb4b77 100644 --- a/jrnl/__version__.py +++ b/jrnl/__version__.py @@ -1 +1 @@ -__version__ = "v2.8.1" +__version__ = "v2.8.2-beta" diff --git a/pyproject.toml b/pyproject.toml index 5c6d5cbd..45c2b58c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "jrnl" -version = "v2.8.1" +version = "v2.8.2-beta" description = "Collect your thoughts and notes without leaving the command line." authors = [ "jrnl contributors ", @@ -47,10 +47,10 @@ tzlocal = ">2.0, <3.0" # https://github.com/regebro/tzlocal/blob/master/CHANGE # I don't like repeating deps here, but # there's no other way to do this yet until poetry v1.2 releases # see: https://github.com/python-poetry/poetry/issues/1644 -behave = { version = "^1.2" , optional = true } -pytest = { version = ">=6.2" , optional = true } -pytest-bdd = { version = ">=4.0.1" , optional = true } -toml = { version = ">=0.10" , optional = true } +behave = { version = "^1.2", optional = true } +pytest = { version = ">=6.2", optional = true } +pytest-bdd = { version = ">=4.0.1", optional = true } +toml = { version = ">=0.10", optional = true } [tool.poetry.dev-dependencies] behave = "^1.2" From 1ba1b756c9cb626737929c0d75ee415485265e93 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 17 Jul 2021 22:17:56 +0000 Subject: [PATCH 168/215] Update changelog [ci skip] --- CHANGELOG.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b43053e2..2d78dcdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ # Changelog -## [Unreleased](https://github.com/jrnl-org/jrnl/) +## [v2.8.2-beta](https://pypi.org/project/jrnl/v2.8.2-beta/) (2021-07-17) -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.1...HEAD) +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.1...v2.8.2-beta) **Implemented enhancements:** @@ -11,8 +11,11 @@ **Build:** - Move test suite entirely to Pytest \(replace Behave\) [\#1192](https://github.com/jrnl-org/jrnl/issues/1192) +- Fix lock file from stable Poetry version [\#1298](https://github.com/jrnl-org/jrnl/pull/1298) ([wren](https://github.com/wren)) +- Change all YAML FullLoader calls to SafeLoader [\#1285](https://github.com/jrnl-org/jrnl/pull/1285) ([micahellison](https://github.com/micahellison)) - Remove useless shebangs and executable permissions [\#1283](https://github.com/jrnl-org/jrnl/pull/1283) ([musicinmybrain](https://github.com/musicinmybrain)) - Add Python 3.10 support [\#1271](https://github.com/jrnl-org/jrnl/pull/1271) ([micahellison](https://github.com/micahellison)) +- Ensure that line endings in all py files are Linux style instead of Windows [\#1250](https://github.com/jrnl-org/jrnl/pull/1250) ([micahellison](https://github.com/micahellison)) - Remove `--version` from brew release workflow [\#1233](https://github.com/jrnl-org/jrnl/pull/1233) ([wren](https://github.com/wren)) - Move test suite to Pytest \(replace Behave\) [\#1193](https://github.com/jrnl-org/jrnl/pull/1193) ([wren](https://github.com/wren)) @@ -21,6 +24,7 @@ - Create security.md [\#1284](https://github.com/jrnl-org/jrnl/issues/1284) - Document keyring security concerns on Windows, Mac [\#1142](https://github.com/jrnl-org/jrnl/issues/1142) - Add documentation about saved passwords in Windows [\#1301](https://github.com/jrnl-org/jrnl/pull/1301) ([micahellison](https://github.com/micahellison)) +- Add security.md [\#1299](https://github.com/jrnl-org/jrnl/pull/1299) ([micahellison](https://github.com/micahellison)) **Packaging:** From c9c6e7efc17f7f706f5b2318aeb8ba09629149ea Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 31 Jul 2021 11:43:19 -0700 Subject: [PATCH 169/215] Fix typo in --help (#1309) --- jrnl/args.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jrnl/args.py b/jrnl/args.py index c8bd7743..972fe802 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -331,7 +331,7 @@ def parse_args(args=[]): Examples: \n \t - Use a different editor for this jrnl entry, call: \n - \t jrnl --config-override editor: "nano" \n + \t jrnl --config-override editor "nano" \n \t - Override color selections\n \t jrnl --config-override colors.body blue --config-override colors.title green """, From 642155292a1eb2cf3dd2ef8f4b83b97565290a12 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 31 Jul 2021 11:45:19 -0700 Subject: [PATCH 170/215] Bump mkdocs from 1.2.1 to 1.2.2 (#1307) Bumps [mkdocs](https://github.com/mkdocs/mkdocs) from 1.2.1 to 1.2.2. - [Release notes](https://github.com/mkdocs/mkdocs/releases) - [Commits](https://github.com/mkdocs/mkdocs/compare/1.2.1...1.2.2) --- updated-dependencies: - dependency-name: mkdocs dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 94b251d3..d7157ffe 100644 --- a/poetry.lock +++ b/poetry.lock @@ -426,7 +426,7 @@ python-versions = ">=3.6" [[package]] name = "mkdocs" -version = "1.2.1" +version = "1.2.2" description = "Project documentation with Markdown." category = "dev" optional = false @@ -1136,8 +1136,8 @@ mergedeep = [ {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, ] mkdocs = [ - {file = "mkdocs-1.2.1-py3-none-any.whl", hash = "sha256:11141126e5896dd9d279b3e4814eb488e409a0990fb638856255020406a8e2e7"}, - {file = "mkdocs-1.2.1.tar.gz", hash = "sha256:6e0ea175366e3a50d334597b0bc042b8cebd512398cdd3f6f34842d0ef524905"}, + {file = "mkdocs-1.2.2-py3-none-any.whl", hash = "sha256:d019ff8e17ec746afeb54eb9eb4112b5e959597aebc971da46a5c9486137f0ff"}, + {file = "mkdocs-1.2.2.tar.gz", hash = "sha256:a334f5bd98ec960638511366eb8c5abc9c99b9083a0ed2401d8791b112d6b078"}, ] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, From c49853d724fa1254d491b73aef90a8fd05c890bd Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 31 Jul 2021 18:47:00 +0000 Subject: [PATCH 171/215] Update changelog [ci skip] --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d78dcdb..120dd3f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [Unreleased](https://github.com/jrnl-org/jrnl/) + +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.2-beta...HEAD) + +**Packaging:** + +- Bump mkdocs from 1.2.1 to 1.2.2 [\#1307](https://github.com/jrnl-org/jrnl/pull/1307) ([dependabot[bot]](https://github.com/apps/dependabot)) + ## [v2.8.2-beta](https://pypi.org/project/jrnl/v2.8.2-beta/) (2021-07-17) [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.1...v2.8.2-beta) From eaaa7bb0e10df4ffd2a189a723e0c687305cb47a Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 31 Jul 2021 19:10:05 +0000 Subject: [PATCH 172/215] Increment version to v2.8.2 --- jrnl/__version__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jrnl/__version__.py b/jrnl/__version__.py index 62fb4b77..04987f5e 100644 --- a/jrnl/__version__.py +++ b/jrnl/__version__.py @@ -1 +1 @@ -__version__ = "v2.8.2-beta" +__version__ = "v2.8.2" diff --git a/pyproject.toml b/pyproject.toml index 45c2b58c..feaf897d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "jrnl" -version = "v2.8.2-beta" +version = "v2.8.2" description = "Collect your thoughts and notes without leaving the command line." authors = [ "jrnl contributors ", From b23c831da5b20122791279614b10e5a365dd18d9 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 31 Jul 2021 19:11:33 +0000 Subject: [PATCH 173/215] Update changelog [ci skip] --- CHANGELOG.md | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 120dd3f2..ef50d24e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,24 +1,12 @@ # Changelog -## [Unreleased](https://github.com/jrnl-org/jrnl/) +## [v2.8.2](https://pypi.org/project/jrnl/v2.8.2/) (2021-07-31) -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.2-beta...HEAD) - -**Packaging:** - -- Bump mkdocs from 1.2.1 to 1.2.2 [\#1307](https://github.com/jrnl-org/jrnl/pull/1307) ([dependabot[bot]](https://github.com/apps/dependabot)) - -## [v2.8.2-beta](https://pypi.org/project/jrnl/v2.8.2-beta/) (2021-07-17) - -[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.1...v2.8.2-beta) - -**Implemented enhancements:** - -- Python 3.10 support [\#1270](https://github.com/jrnl-org/jrnl/issues/1270) +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.2-beta...v2.8.2) **Build:** -- Move test suite entirely to Pytest \(replace Behave\) [\#1192](https://github.com/jrnl-org/jrnl/issues/1192) +- Add CI tests for latest dev Python build [\#1273](https://github.com/jrnl-org/jrnl/issues/1273) - Fix lock file from stable Poetry version [\#1298](https://github.com/jrnl-org/jrnl/pull/1298) ([wren](https://github.com/wren)) - Change all YAML FullLoader calls to SafeLoader [\#1285](https://github.com/jrnl-org/jrnl/pull/1285) ([micahellison](https://github.com/micahellison)) - Remove useless shebangs and executable permissions [\#1283](https://github.com/jrnl-org/jrnl/pull/1283) ([musicinmybrain](https://github.com/musicinmybrain)) @@ -29,13 +17,12 @@ **Documentation:** -- Create security.md [\#1284](https://github.com/jrnl-org/jrnl/issues/1284) -- Document keyring security concerns on Windows, Mac [\#1142](https://github.com/jrnl-org/jrnl/issues/1142) - Add documentation about saved passwords in Windows [\#1301](https://github.com/jrnl-org/jrnl/pull/1301) ([micahellison](https://github.com/micahellison)) - Add security.md [\#1299](https://github.com/jrnl-org/jrnl/pull/1299) ([micahellison](https://github.com/micahellison)) **Packaging:** +- Bump mkdocs from 1.2.1 to 1.2.2 [\#1307](https://github.com/jrnl-org/jrnl/pull/1307) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump python-dateutil from 2.8.1 to 2.8.2 [\#1302](https://github.com/jrnl-org/jrnl/pull/1302) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump black from 21.5b1 to 21.5b2 [\#1254](https://github.com/jrnl-org/jrnl/pull/1254) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump black from 21.5b0 to 21.5b1 [\#1244](https://github.com/jrnl-org/jrnl/pull/1244) ([dependabot[bot]](https://github.com/apps/dependabot)) From 8a64b77e63612bddcdbd50969cfb5eee630ddbc8 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Mon, 16 Aug 2021 19:46:01 -0700 Subject: [PATCH 174/215] Update build to poetry alpha 2 for python 3.10 (#1320) * udpate build to poetry alpha 2 for python 3.10 * update testing workflow to run when workflow itself is changed --- .github/workflows/testing.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index 396fc854..d2ec4039 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -9,6 +9,7 @@ on: - 'tests/**' - 'poetry.lock' - 'pyproject.toml' + - '.github/workflows/testing.yaml' pull_request: branches: [ develop ] paths: @@ -17,6 +18,7 @@ on: - 'tests/**' - 'poetry.lock' - 'pyproject.toml' + - '.github/workflows/testing.yaml' jobs: test: @@ -64,7 +66,7 @@ jobs: if: ${{ matrix.python-version == '3.10-dev' }} run: | echo '::group::poetry' - pip install poetry==1.2.0a1 + pip install poetry==1.2.0a2 poetry config --local virtualenvs.in-project true echo '::endgroup::' From 5ec7dec9f01ca3504f5d99c9a2f9108540ca466b Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Tue, 17 Aug 2021 02:47:47 +0000 Subject: [PATCH 175/215] Update changelog [ci skip] --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef50d24e..5b798f2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [Unreleased](https://github.com/jrnl-org/jrnl/) + +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.2...HEAD) + +**Implemented enhancements:** + +- Output after composition can be more useful and user friendly [\#1253](https://github.com/jrnl-org/jrnl/issues/1253) + +**Build:** + +- Python 3.10 build action is failing on poetry dependency installation [\#1321](https://github.com/jrnl-org/jrnl/issues/1321) + ## [v2.8.2](https://pypi.org/project/jrnl/v2.8.2/) (2021-07-31) [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.2-beta...v2.8.2) From 3b93e92960729e5a062605b08ba9f775bb67e578 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Mon, 16 Aug 2021 20:13:44 -0700 Subject: [PATCH 176/215] take out arg for old plugin from makefile (#1322) --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a4494ee3..b2e27f32 100644 --- a/Makefile +++ b/Makefile @@ -25,10 +25,10 @@ unit: # unit tests poetry run pytest tests/unit bdd: # bdd tests - poetry run pytest tests/bdd --gherkin-terminal-reporter --tb=native --diff-type=unified + poetry run pytest tests/bdd --gherkin-terminal-reporter --tb=native bdd-debug: # bdd tests - poetry run pytest tests/bdd --gherkin-terminal-reporter --tb=native --diff-type=unified -x -vv + poetry run pytest tests/bdd --gherkin-terminal-reporter --tb=native -x -vv test: lint unit bdd ## Run unit tests and behave tests From 32b5a2b5d0c313225e1407d85b78460eee6b8e7f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Aug 2021 20:22:39 -0700 Subject: [PATCH 177/215] Bump keyring from 23.0.1 to 23.1.0 (#1318) Bumps [keyring](https://github.com/jaraco/keyring) from 23.0.1 to 23.1.0. - [Release notes](https://github.com/jaraco/keyring/releases) - [Changelog](https://github.com/jaraco/keyring/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/keyring/compare/v23.0.1...v23.1.0) --- updated-dependencies: - dependency-name: keyring dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index d7157ffe..f2b0dcb5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -344,7 +344,7 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "keyring" -version = "23.0.1" +version = "23.1.0" description = "Store and access your passwords safely." category = "main" optional = false @@ -1026,8 +1026,10 @@ cryptography = [ {file = "cryptography-3.4.7-cp36-abi3-win_amd64.whl", hash = "sha256:de4e5f7f68220d92b7637fc99847475b59154b7a1b3868fb7385337af54ac9ca"}, {file = "cryptography-3.4.7-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:26965837447f9c82f1855e0bc8bc4fb910240b6e0d16a664bb722df3b5b06873"}, {file = "cryptography-3.4.7-pp36-pypy36_pp73-manylinux2014_x86_64.whl", hash = "sha256:eb8cc2afe8b05acbd84a43905832ec78e7b3873fb124ca190f574dca7389a87d"}, + {file = "cryptography-3.4.7-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b01fd6f2737816cb1e08ed4807ae194404790eac7ad030b34f2ce72b332f5586"}, {file = "cryptography-3.4.7-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:7ec5d3b029f5fa2b179325908b9cd93db28ab7b85bb6c1db56b10e0b54235177"}, {file = "cryptography-3.4.7-pp37-pypy37_pp73-manylinux2014_x86_64.whl", hash = "sha256:ee77aa129f481be46f8d92a1a7db57269a2f23052d5f2433b4621bb457081cc9"}, + {file = "cryptography-3.4.7-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:bf40af59ca2465b24e54f671b2de2c59257ddc4f7e5706dbd6930e26823668d3"}, {file = "cryptography-3.4.7.tar.gz", hash = "sha256:3d10de8116d25649631977cb37da6cbdd2d6fa0e0281d014a5b7d337255ca713"}, ] decorator = [ @@ -1076,8 +1078,8 @@ jinja2 = [ {file = "Jinja2-3.0.1.tar.gz", hash = "sha256:703f484b47a6af502e743c9122595cc812b0271f661722403114f71a79d0f5a4"}, ] keyring = [ - {file = "keyring-23.0.1-py3-none-any.whl", hash = "sha256:8f607d7d1cc502c43a932a275a56fe47db50271904513a379d39df1af277ac48"}, - {file = "keyring-23.0.1.tar.gz", hash = "sha256:045703609dd3fccfcdb27da201684278823b72af515aedec1a8515719a038cb8"}, + {file = "keyring-23.1.0-py3-none-any.whl", hash = "sha256:b32397fd7e7063f8dd74a26db910c9862fc2109285fa16e3b5208bcb42a3e579"}, + {file = "keyring-23.1.0.tar.gz", hash = "sha256:b7e0156667f5dcc73c1f63a518005cd18a4eb23fe77321194fefcc03748b21a4"}, ] mako = [ {file = "Mako-1.1.4-py2.py3-none-any.whl", hash = "sha256:aea166356da44b9b830c8023cd9b557fa856bd8b4035d6de771ca027dfc5cc6e"}, @@ -1088,12 +1090,22 @@ markdown = [ {file = "Markdown-3.3.4.tar.gz", hash = "sha256:31b5b491868dcc87d6c24b7e3d19a0d730d59d3e46f4eea6430a321bed387a49"}, ] markupsafe = [ + {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, @@ -1102,14 +1114,21 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, @@ -1119,6 +1138,9 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, @@ -1289,6 +1311,10 @@ regex = [ {file = "regex-2021.7.6-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:b85ac458354165405c8a84725de7bbd07b00d9f72c31a60ffbf96bb38d3e25fa"}, {file = "regex-2021.7.6-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:3f5716923d3d0bfb27048242a6e0f14eecdb2e2a7fac47eda1d055288595f222"}, {file = "regex-2021.7.6-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5983c19d0beb6af88cb4d47afb92d96751fb3fa1784d8785b1cdf14c6519407"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf1d2d183abc7faa101ebe0b8d04fd19cb9138820abc8589083035c9440b8ca6"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1947e7de155063e1c495c50590229fb98720d4c383af5031bbcb413db33fa1be"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:17d8a3f99b18d87ac54a449b836d485cc8c195bb6f5e4379c84c8519045facc9"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d30895ec80cc80358392841add9dde81ea1d54a4949049269115e6b0555d0498"}, {file = "regex-2021.7.6-cp36-cp36m-win32.whl", hash = "sha256:c92831dac113a6e0ab28bc98f33781383fe294df1a2c3dfd1e850114da35fd5b"}, {file = "regex-2021.7.6-cp36-cp36m-win_amd64.whl", hash = "sha256:791aa1b300e5b6e5d597c37c346fb4d66422178566bbb426dd87eaae475053fb"}, {file = "regex-2021.7.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:59506c6e8bd9306cd8a41511e32d16d5d1194110b8cfe5a11d102d8b63cf945d"}, @@ -1299,6 +1325,10 @@ regex = [ {file = "regex-2021.7.6-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:173bc44ff95bc1e96398c38f3629d86fa72e539c79900283afa895694229fe6a"}, {file = "regex-2021.7.6-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:15dddb19823f5147e7517bb12635b3c82e6f2a3a6b696cc3e321522e8b9308ad"}, {file = "regex-2021.7.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ddeabc7652024803666ea09f32dd1ed40a0579b6fbb2a213eba590683025895"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8244c681018423a0d1784bc6b9af33bdf55f2ab8acb1f3cd9dd83d90e0813253"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8a4c742089faf0e51469c6a1ad7e3d3d21afae54a16a6cead85209dfe0a1ce65"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:914e626dc8e75fe4fc9b7214763f141d9f40165d00dfe680b104fa1b24063bbf"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3fabb19c82ecf39832a3f5060dfea9a7ab270ef156039a1143a29a83a09a62de"}, {file = "regex-2021.7.6-cp37-cp37m-win32.whl", hash = "sha256:f080248b3e029d052bf74a897b9d74cfb7643537fbde97fe8225a6467fb559b5"}, {file = "regex-2021.7.6-cp37-cp37m-win_amd64.whl", hash = "sha256:d8bbce0c96462dbceaa7ac4a7dfbbee92745b801b24bce10a98d2f2b1ea9432f"}, {file = "regex-2021.7.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:edd1a68f79b89b0c57339bce297ad5d5ffcc6ae7e1afdb10f1947706ed066c9c"}, @@ -1309,6 +1339,10 @@ regex = [ {file = "regex-2021.7.6-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:bc84fb254a875a9f66616ed4538542fb7965db6356f3df571d783f7c8d256edd"}, {file = "regex-2021.7.6-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:598c0a79b4b851b922f504f9f39a863d83ebdfff787261a5ed061c21e67dd761"}, {file = "regex-2021.7.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875c355360d0f8d3d827e462b29ea7682bf52327d500a4f837e934e9e4656068"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfc0957c4a4b91eff5ad036088769e600a25774256cd0e1154378591ce573f08"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efb4af05fa4d2fc29766bf516f1f5098d6b5c3ed846fde980c18bf8646ad3979"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7423aca7cc30a6228ccdcf2ea76f12923d652c5c7c6dc1959a0b004e308f39fb"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bb9834c1e77493efd7343b8e38950dee9797d2d6f2d5fd91c008dfaef64684b9"}, {file = "regex-2021.7.6-cp38-cp38-win32.whl", hash = "sha256:e586f448df2bbc37dfadccdb7ccd125c62b4348cb90c10840d695592aa1b29e0"}, {file = "regex-2021.7.6-cp38-cp38-win_amd64.whl", hash = "sha256:2fe5e71e11a54e3355fa272137d521a40aace5d937d08b494bed4529964c19c4"}, {file = "regex-2021.7.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6110bab7eab6566492618540c70edd4d2a18f40ca1d51d704f1d81c52d245026"}, @@ -1319,6 +1353,10 @@ regex = [ {file = "regex-2021.7.6-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:2bceeb491b38225b1fee4517107b8491ba54fba77cf22a12e996d96a3c55613d"}, {file = "regex-2021.7.6-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:f98dc35ab9a749276f1a4a38ab3e0e2ba1662ce710f6530f5b0a6656f1c32b58"}, {file = "regex-2021.7.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:319eb2a8d0888fa6f1d9177705f341bc9455a2c8aca130016e52c7fe8d6c37a3"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:598ee917dbe961dcf827217bf2466bb86e4ee5a8559705af57cbabb3489dd37e"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:56fc7045a1999a8d9dd1896715bc5c802dfec5b9b60e883d2cbdecb42adedea4"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8363ac90ea63c3dd0872dfdb695f38aff3334bfa5712cffb238bd3ffef300e3"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:716a6db91b3641f566531ffcc03ceec00b2447f0db9942b3c6ea5d2827ad6be3"}, {file = "regex-2021.7.6-cp39-cp39-win32.whl", hash = "sha256:eaf58b9e30e0e546cdc3ac06cf9165a1ca5b3de8221e9df679416ca667972035"}, {file = "regex-2021.7.6-cp39-cp39-win_amd64.whl", hash = "sha256:4c9c3155fe74269f61e27617529b7f09552fbb12e44b1189cebbdb24294e6e1c"}, {file = "regex-2021.7.6.tar.gz", hash = "sha256:8394e266005f2d8c6f0bc6780001f7afa3ef81a7a2111fa35058ded6fce79e4d"}, From 1c63d9473699cda1fab3f3e39e9e929b1747596b Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Tue, 17 Aug 2021 03:24:18 +0000 Subject: [PATCH 178/215] Update changelog [ci skip] --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b798f2d..98a8c5bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ - Python 3.10 build action is failing on poetry dependency installation [\#1321](https://github.com/jrnl-org/jrnl/issues/1321) +**Packaging:** + +- Bump keyring from 23.0.1 to 23.1.0 [\#1318](https://github.com/jrnl-org/jrnl/pull/1318) ([dependabot[bot]](https://github.com/apps/dependabot)) + ## [v2.8.2](https://pypi.org/project/jrnl/v2.8.2/) (2021-07-31) [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.2-beta...v2.8.2) From a0a3ef669e11c50c81b9dbf2b3064de6e8b818b3 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 21 Aug 2021 12:08:44 -0700 Subject: [PATCH 179/215] Set bash as default shell (#1324) --- .github/workflows/testing.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index d2ec4039..2976399f 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -20,6 +20,10 @@ on: - 'pyproject.toml' - '.github/workflows/testing.yaml' +defaults: + run: + shell: bash # needed to prevent Windows from using PowerShell + jobs: test: if: > From 9de723d01450ba6a1c5b1ad24145e003fa78822a Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 21 Aug 2021 19:10:25 +0000 Subject: [PATCH 180/215] Update changelog [ci skip] --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98a8c5bb..29898eca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,9 @@ **Build:** +- Windows CI behaving unreliable due to mismatch between Powershell & bash retrieving environment variables [\#1323](https://github.com/jrnl-org/jrnl/issues/1323) - Python 3.10 build action is failing on poetry dependency installation [\#1321](https://github.com/jrnl-org/jrnl/issues/1321) +- Set bash as default shell [\#1324](https://github.com/jrnl-org/jrnl/pull/1324) ([micahellison](https://github.com/micahellison)) **Packaging:** From 3e5a55b1e9841d86de059eaa67800976e780fb4e Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 21 Aug 2021 13:46:29 -0700 Subject: [PATCH 181/215] Display error when trying to encrypt folder/DayOne journal types (#1315) * Raise exception when trying to commit folder-based journal (including DayOne) * Add test to ensure this doesn't mess with encrypting normal journals * Consolidate and standardized tests --- jrnl/DayOneJournal.py | 1 + jrnl/FolderJournal.py | 1 + jrnl/commands.py | 8 ++++++++ jrnl/exception.py | 7 +++++++ tests/bdd/features/encrypt.feature | 19 +++++++++++++++++-- 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/jrnl/DayOneJournal.py b/jrnl/DayOneJournal.py index 01b934e5..1e484365 100644 --- a/jrnl/DayOneJournal.py +++ b/jrnl/DayOneJournal.py @@ -32,6 +32,7 @@ class DayOne(Journal.Journal): def __init__(self, **kwargs): self.entries = [] self._deleted_entries = [] + self.can_be_encrypted = False super().__init__(**kwargs) def open(self): diff --git a/jrnl/FolderJournal.py b/jrnl/FolderJournal.py index 954a9436..0c67a141 100644 --- a/jrnl/FolderJournal.py +++ b/jrnl/FolderJournal.py @@ -25,6 +25,7 @@ class Folder(Journal.Journal): def __init__(self, **kwargs): self.entries = [] self._diff_entry_dates = [] + self.can_be_encrypted = False super(Folder, self).__init__(**kwargs) def open(self): diff --git a/jrnl/commands.py b/jrnl/commands.py index 07ca0767..d765242a 100644 --- a/jrnl/commands.py +++ b/jrnl/commands.py @@ -13,6 +13,7 @@ avoid any possible overhead for these standalone commands. """ import platform import sys +from .exception import JrnlError def preconfig_diagnostic(_): @@ -68,6 +69,13 @@ def postconfig_encrypt(args, config, original_config, **kwargs): # Open the journal journal = open_journal(args.journal_name, config) + if hasattr(journal, "can_be_encrypted") and not journal.can_be_encrypted: + raise JrnlError( + "CannotEncryptJournalType", + journal_name=args.journal_name, + journal_type=journal.__class__.__name__, + ) + journal.config["encrypt"] = True new_journal = EncryptedJournal.from_journal(journal) diff --git a/jrnl/exception.py b/jrnl/exception.py index 07bf9023..0bafbdeb 100644 --- a/jrnl/exception.py +++ b/jrnl/exception.py @@ -38,6 +38,13 @@ class JrnlError(Exception): by at least {columns} in the configuration file or by using --config-override at the command line """, + "CannotEncryptJournalType": """ + The journal {journal_name} can't be encrypted because it is a + {journal_type} journal. + + To encrypt it, create a new journal referencing a file, export + this journal to the new journal, then encrypt the new journal. + """, } msg = error_messages[self.error_type].format(**kwargs) diff --git a/tests/bdd/features/encrypt.feature b/tests/bdd/features/encrypt.feature index 31d53520..02bff32f 100644 --- a/tests/bdd/features/encrypt.feature +++ b/tests/bdd/features/encrypt.feature @@ -28,15 +28,30 @@ 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" + Examples: configs + | config_file | + | basic_onefile.yaml | + + + Scenario Outline: Attempt to encrypt a folder or DayOne journal should result in an error + Given we use the config "" + 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 | From bacbf8109bc4b968fbd9010953fe7592d33d259a Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 21 Aug 2021 20:48:08 +0000 Subject: [PATCH 182/215] Update changelog [ci skip] --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29898eca..8ece5f28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ - Output after composition can be more useful and user friendly [\#1253](https://github.com/jrnl-org/jrnl/issues/1253) +**Fixed bugs:** + +- Uncaught exception when encrypting folder journal [\#1243](https://github.com/jrnl-org/jrnl/issues/1243) + **Build:** - Windows CI behaving unreliable due to mismatch between Powershell & bash retrieving environment variables [\#1323](https://github.com/jrnl-org/jrnl/issues/1323) From 08350b884b86201e4cc1889987019199acaa1e40 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 21 Aug 2021 14:00:31 -0700 Subject: [PATCH 183/215] take out redundant lines from PR template (#1327) --- .github/PULL_REQUEST_TEMPLATE.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1d3f0f07..695290e8 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -14,11 +14,9 @@ Here are some key points to include in your description: - [ ] I have read the [contributing doc](https://github.com/jrnl-org/jrnl/blob/develop/CONTRIBUTING.md). - [ ] I have included a link to the relevant issue number. -- [ ] I have tested this code locally. - [ ] I have checked to ensure there aren't other open [pull requests](../pulls) for the same issue. - [ ] I have written new tests for these changes, as needed. -- [ ] All tests pass. +# Journal Types +`jrnl` can store your journal in a few different ways: + + - a single text file (encrypted or otherwise) + - a folder structure organized by date containing unencrypted text files + - the DayOne Classic format + +There is no need to specify what type of journal you'd like to use. Instead, +`jrnl` will automatically detect the journal type based on whether you're +referencing a file or a folder in your [config file](advanced.md), +and if it's a folder, whether or not DayOne Classic content exists in it. + +## Single File +The single file format is the most flexible, as it can be [encrypted](encryption.md). +To use it, enter any path that is a file or does not already exist. You can +use any extension. `jrnl` will automatically create the file when you save +your first entry. + +## Folder +The folder journal format organizes your entries into subfolders for the year +and month and `.txt` files for each day. If there are multiple entries in a day, +they all appear in the same `.txt` file. + +The directory tree structure is in this format: `YYYY/MM/DD.txt`. For instance, if +you have an entry on May 5th, 2021 in a folder journal at `~/folderjournal`, it will +be located in: `~/folderjournal/2021/05/05.txt` + +!!! note +When creating a new folder journal, you will need to create the folder before running +`jrnl`. Otherwise, when you run `jrnl` for the first time, it will assume that you +are creating a single file journal instead, and it will create a file at that path. + +!!! note +Folder journals can't be encrypted. + +## Day One Classic +`jrnl` supports the original data format used by DayOne. It's similar to the folder +journal format, except it's identified by either of these characteristics: + +* the folder has a `.dayone` extension +* the folder has a subfolder named `entries` + +This is not to be confused with the DayOne 2.0 format, [which is very different](https://help.dayoneapp.com/en/articles/1187337-day-one-classic-is-retired). + +!!! note +DayOne Classic journals can't be encrypted. + +## Changing your journal type +You can't simply modify a journal's configuration to change its type. Instead, +define a new journal as the type you'd like, and use +[piping](https://en.wikipedia.org/wiki/Redirection_(computing)#Piping) +to export your old journal as `txt` to an import command on your new journal. + +For instance, if you have a `projects` journal you would like to import into +a `new` journal, you would run the following after setting up the configuration +for your `new` journal: +``` +jrnl projects --format txt | jrnl new --import +``` diff --git a/mkdocs.yml b/mkdocs.yml index 65a515da..348f0a83 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -21,6 +21,7 @@ nav: - Quickstart: installation.md - Basic Usage: usage.md - Encryption: encryption.md + - Journal Types: journal-types.md - Privacy and Security: privacy-and-security.md - Formats: formats.md - Advanced Usage: advanced.md From 9f16cc42f5a833da0035b08c0bbe1fedc3ca1271 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 18 Sep 2021 23:28:00 +0000 Subject: [PATCH 207/215] Update changelog [ci skip] --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7c50316..9dca20c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,9 @@ **Documentation:** +- Document folder journal and DayOne journal types [\#1326](https://github.com/jrnl-org/jrnl/issues/1326) - Fix readme splash and add changelog link to readme [\#1339](https://github.com/jrnl-org/jrnl/pull/1339) ([micahellison](https://github.com/micahellison)) +- Document journal types [\#1331](https://github.com/jrnl-org/jrnl/pull/1331) ([micahellison](https://github.com/micahellison)) **Packaging:** From 4c0fb344d1d5f7aac5095eddf619e35649b12fa1 Mon Sep 17 00:00:00 2001 From: Micah Jerome Ellison Date: Sat, 25 Sep 2021 11:11:28 -0700 Subject: [PATCH 208/215] Add CACHE_STRING secret to bust GitHub Actions python cache (#1344) * Add CACHE_STRING secret to allow maintainers to bust cache without a commit * Quick change Co-authored-by: Jonathan Wren --- .github/workflows/testing.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index 2976399f..c6cf4c73 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -45,11 +45,11 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: poetry cache + - name: poetry cache # Change CACHE_STRING secret to bust the cache. Useful with minor Python version changes. uses: actions/cache@v2 with: path: .venv - key: ${{ runner.os }}-${{ hashFiles('poetry.lock') }}-${{ matrix.python-version }}-v2 + key: ${{ runner.os }}-${{ hashFiles('poetry.lock') }}-${{ matrix.python-version }}-${{ secrets.CACHE_STRING }} - name: Install dependencies if: ${{ matrix.python-version != '3.10-dev' }} From 60c9ed124dd1f894731518c641f4e744d159e0cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 2 Oct 2021 12:23:17 -0700 Subject: [PATCH 209/215] Bump cryptography from 3.4.8 to 35.0.0 (#1345) Bumps [cryptography](https://github.com/pyca/cryptography) from 3.4.8 to 35.0.0. - [Release notes](https://github.com/pyca/cryptography/releases) - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/3.4.8...35.0.0) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 57 +++++++++++++++++++++++------------------------------ 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/poetry.lock b/poetry.lock index d55ab429..cc5e4e26 100644 --- a/poetry.lock +++ b/poetry.lock @@ -158,7 +158,7 @@ test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] [[package]] name = "cryptography" -version = "3.4.8" +version = "35.0.0" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false @@ -171,9 +171,9 @@ cffi = ">=1.12" docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] -sdist = ["setuptools-rust (>=0.11.4)"] +sdist = ["setuptools_rust (>=0.11.4)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["pytest (>=6.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] +test = ["pytest (>=6.2.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] [[package]] name = "decorator" @@ -209,7 +209,7 @@ python-versions = "*" python-dateutil = ">=2.8.1" [package.extras] -dev = ["twine", "markdown", "flake8"] +dev = ["twine", "markdown", "flake8", "wheel"] [[package]] name = "glob2" @@ -842,14 +842,6 @@ category = "dev" optional = false python-versions = "*" -[[package]] -name = "typing-extensions" -version = "3.10.0.0" -description = "Backported and Experimental Type Hints for Python 3.5+" -category = "main" -optional = false -python-versions = "*" - [[package]] name = "typing-extensions" version = "3.10.0.2" @@ -1029,23 +1021,26 @@ commonmark = [ {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, ] cryptography = [ - {file = "cryptography-3.4.8-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:a00cf305f07b26c351d8d4e1af84ad7501eca8a342dedf24a7acb0e7b7406e14"}, - {file = "cryptography-3.4.8-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:f44d141b8c4ea5eb4dbc9b3ad992d45580c1d22bf5e24363f2fbf50c2d7ae8a7"}, - {file = "cryptography-3.4.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0a7dcbcd3f1913f664aca35d47c1331fce738d44ec34b7be8b9d332151b0b01e"}, - {file = "cryptography-3.4.8-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34dae04a0dce5730d8eb7894eab617d8a70d0c97da76b905de9efb7128ad7085"}, - {file = "cryptography-3.4.8-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1eb7bb0df6f6f583dd8e054689def236255161ebbcf62b226454ab9ec663746b"}, - {file = "cryptography-3.4.8-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:9965c46c674ba8cc572bc09a03f4c649292ee73e1b683adb1ce81e82e9a6a0fb"}, - {file = "cryptography-3.4.8-cp36-abi3-win32.whl", hash = "sha256:21ca464b3a4b8d8e86ba0ee5045e103a1fcfac3b39319727bc0fc58c09c6aff7"}, - {file = "cryptography-3.4.8-cp36-abi3-win_amd64.whl", hash = "sha256:3520667fda779eb788ea00080124875be18f2d8f0848ec00733c0ec3bb8219fc"}, - {file = "cryptography-3.4.8-pp36-pypy36_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d2a6e5ef66503da51d2110edf6c403dc6b494cc0082f85db12f54e9c5d4c3ec5"}, - {file = "cryptography-3.4.8-pp36-pypy36_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a305600e7a6b7b855cd798e00278161b681ad6e9b7eca94c721d5f588ab212af"}, - {file = "cryptography-3.4.8-pp36-pypy36_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:3fa3a7ccf96e826affdf1a0a9432be74dc73423125c8f96a909e3835a5ef194a"}, - {file = "cryptography-3.4.8-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:d9ec0e67a14f9d1d48dd87a2531009a9b251c02ea42851c060b25c782516ff06"}, - {file = "cryptography-3.4.8-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5b0fbfae7ff7febdb74b574055c7466da334a5371f253732d7e2e7525d570498"}, - {file = "cryptography-3.4.8-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94fff993ee9bc1b2440d3b7243d488c6a3d9724cc2b09cdb297f6a886d040ef7"}, - {file = "cryptography-3.4.8-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:8695456444f277af73a4877db9fc979849cd3ee74c198d04fc0776ebc3db52b9"}, - {file = "cryptography-3.4.8-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:cd65b60cfe004790c795cc35f272e41a3df4631e2fb6b35aa7ac6ef2859d554e"}, - {file = "cryptography-3.4.8.tar.gz", hash = "sha256:94cc5ed4ceaefcbe5bf38c8fba6a21fc1d365bb8fb826ea1688e3370b2e24a1c"}, + {file = "cryptography-35.0.0-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:d57e0cdc1b44b6cdf8af1d01807db06886f10177469312fbde8f44ccbb284bc9"}, + {file = "cryptography-35.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:ced40344e811d6abba00295ced98c01aecf0c2de39481792d87af4fa58b7b4d6"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:54b2605e5475944e2213258e0ab8696f4f357a31371e538ef21e8d61c843c28d"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:7b7ceeff114c31f285528ba8b390d3e9cfa2da17b56f11d366769a807f17cbaa"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d69645f535f4b2c722cfb07a8eab916265545b3475fdb34e0be2f4ee8b0b15e"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2d0e0acc20ede0f06ef7aa58546eee96d2592c00f450c9acb89c5879b61992"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:07bb7fbfb5de0980590ddfc7f13081520def06dc9ed214000ad4372fb4e3c7f6"}, + {file = "cryptography-35.0.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:7eba2cebca600a7806b893cb1d541a6e910afa87e97acf2021a22b32da1df52d"}, + {file = "cryptography-35.0.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:18d90f4711bf63e2fb21e8c8e51ed8189438e6b35a6d996201ebd98a26abbbe6"}, + {file = "cryptography-35.0.0-cp36-abi3-win32.whl", hash = "sha256:c10c797ac89c746e488d2ee92bd4abd593615694ee17b2500578b63cad6b93a8"}, + {file = "cryptography-35.0.0-cp36-abi3-win_amd64.whl", hash = "sha256:7075b304cd567694dc692ffc9747f3e9cb393cc4aa4fb7b9f3abd6f5c4e43588"}, + {file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a688ebcd08250eab5bb5bca318cc05a8c66de5e4171a65ca51db6bd753ff8953"}, + {file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d99915d6ab265c22873f1b4d6ea5ef462ef797b4140be4c9d8b179915e0985c6"}, + {file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:928185a6d1ccdb816e883f56ebe92e975a262d31cc536429041921f8cb5a62fd"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:ebeddd119f526bcf323a89f853afb12e225902a24d29b55fe18dd6fcb2838a76"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:22a38e96118a4ce3b97509443feace1d1011d0571fae81fc3ad35f25ba3ea999"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb80e8a1f91e4b7ef8b33041591e6d89b2b8e122d787e87eeb2b08da71bb16ad"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:abb5a361d2585bb95012a19ed9b2c8f412c5d723a9836418fab7aaa0243e67d2"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:1ed82abf16df40a60942a8c211251ae72858b25b7421ce2497c2eb7a1cee817c"}, + {file = "cryptography-35.0.0.tar.gz", hash = "sha256:9933f28f70d0517686bd7de36166dda42094eac49415459d9bdf5e7df3e0086d"}, ] decorator = [ {file = "decorator-5.0.9-py3-none-any.whl", hash = "sha256:6e5c199c16f7a9f0e3a61a4a54b3d27e7dad0dbdde92b944426cb20914376323"}, @@ -1057,6 +1052,7 @@ flake8 = [ ] ghp-import = [ {file = "ghp-import-2.0.1.tar.gz", hash = "sha256:753de2eace6e0f7d4edfb3cce5e3c3b98cd52aadb80163303d1d036bda7b4483"}, + {file = "ghp_import-2.0.1-py3-none-any.whl", hash = "sha256:8241a8e9f8dd3c1fafe9696e6e081b57a208ef907e9939c44e7415e407ab40ea"}, ] glob2 = [ {file = "glob2-0.7.tar.gz", hash = "sha256:85c3dbd07c8aa26d63d7aacee34fa86e9a91a3873bc30bf62ec46e531f92ab8c"}, @@ -1441,9 +1437,6 @@ typed-ast = [ {file = "typed_ast-1.4.3.tar.gz", hash = "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65"}, ] typing-extensions = [ - {file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"}, - {file = "typing_extensions-3.10.0.0-py3-none-any.whl", hash = "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"}, - {file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"}, {file = "typing_extensions-3.10.0.2-py2-none-any.whl", hash = "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7"}, {file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"}, {file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"}, From 593245f3fda2d4ae38ef4e7714013edaa32eb120 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 2 Oct 2021 19:24:53 +0000 Subject: [PATCH 210/215] Update changelog [ci skip] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9dca20c8..df5e5d90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ **Packaging:** +- Bump cryptography from 3.4.8 to 35.0.0 [\#1345](https://github.com/jrnl-org/jrnl/pull/1345) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump black from 21.8b0 to 21.9b0 [\#1343](https://github.com/jrnl-org/jrnl/pull/1343) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump keyring from 23.1.0 to 23.2.1 [\#1342](https://github.com/jrnl-org/jrnl/pull/1342) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump pytest from 6.2.4 to 6.2.5 [\#1334](https://github.com/jrnl-org/jrnl/pull/1334) ([dependabot[bot]](https://github.com/apps/dependabot)) From 7d8823da6df9f89bebd232babb2ef157f86c35cb Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 2 Oct 2021 13:31:21 -0700 Subject: [PATCH 211/215] Move remaining tests from behave to pytest (#1346) * add newer tests to pytest (from behave) * remove 'lib' from gitignore (since we're using it) * fix capitalization in some steps * add 'the editor should not have been called' step * comment out config override step in pytest-bdd since it's not implemented yet * remove test that didn't really test anything * implement some missing steps in pytest-bdd * change comment to match other tests --- .gitignore | 1 - tests/bdd/features/format.feature | 44 ++++++++++++++ tests/bdd/features/override.feature | 91 +++++++++++++++++++++++++++++ tests/bdd/test_features.py | 1 + tests/lib/then_steps.py | 35 +++++++++-- 5 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 tests/bdd/features/override.feature diff --git a/.gitignore b/.gitignore index 374deb4b..41d2df7b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,6 @@ var sdist develop-eggs .installed.cfg -lib lib64 .python-version diff --git a/tests/bdd/features/format.feature b/tests/bdd/features/format.feature index b9e2e384..36a89747 100644 --- a/tests/bdd/features/format.feature +++ b/tests/bdd/features/format.feature @@ -1,5 +1,33 @@ Feature: Custom formats + Scenario Outline: Short printing via --format flag + Given we use the config "" + 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 "" + 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 "" 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 "" + 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 diff --git a/tests/bdd/features/override.feature b/tests/bdd/features/override.feature new file mode 100644 index 00000000..3d9fb27f --- /dev/null +++ b/tests/bdd/features/override.feature @@ -0,0 +1,91 @@ +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 + + + # @todo implement this step in pytest (doesn't currently support overrides) + @skip + 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 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. │ + ┖─────────────────────┘ + + + # @todo implement this step in pytest (doesn't currently support overrides) + @skip + 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 should have "colors.body" set to "blue" + + + # @todo implement this step in pytest (doesn't currently support overrides) + @skip + 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 should have "colors.body" set to "green" + And the config should have "editor" set to "nano" + + + 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. diff --git a/tests/bdd/test_features.py b/tests/bdd/test_features.py index b824df39..1509e92d 100644 --- a/tests/bdd/test_features.py +++ b/tests/bdd/test_features.py @@ -9,6 +9,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") diff --git a/tests/lib/then_steps.py b/tests/lib/then_steps.py index b56c203f..2dadf82e 100644 --- a/tests/lib/then_steps.py +++ b/tests/lib/then_steps.py @@ -84,6 +84,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"] @@ -301,15 +309,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"] From 1196b05ff63a155858d8018cc06c6300c874f236 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 9 Oct 2021 11:43:43 -0700 Subject: [PATCH 212/215] Bump pytz from 2021.1 to 2021.3 (#1348) Bumps [pytz](https://github.com/stub42/pytz) from 2021.1 to 2021.3. - [Release notes](https://github.com/stub42/pytz/releases) - [Commits](https://github.com/stub42/pytz/compare/release_2021.1...release_2021.3) --- updated-dependencies: - dependency-name: pytz dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index cc5e4e26..e718ea5a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -710,7 +710,7 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2021.1" +version = "2021.3" description = "World timezone definitions, modern and historical" category = "main" optional = false @@ -1271,8 +1271,8 @@ python-dateutil = [ {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] pytz = [ - {file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"}, - {file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"}, + {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"}, + {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"}, ] pywin32-ctypes = [ {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, From a98f3f78afc1e51fff92c3c25d3b033e4bd1f8b6 Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 9 Oct 2021 18:45:22 +0000 Subject: [PATCH 213/215] Update changelog [ci skip] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index df5e5d90..c47711d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ **Packaging:** +- Bump pytz from 2021.1 to 2021.3 [\#1348](https://github.com/jrnl-org/jrnl/pull/1348) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump cryptography from 3.4.8 to 35.0.0 [\#1345](https://github.com/jrnl-org/jrnl/pull/1345) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump black from 21.8b0 to 21.9b0 [\#1343](https://github.com/jrnl-org/jrnl/pull/1343) ([dependabot[bot]](https://github.com/apps/dependabot)) - Bump keyring from 23.1.0 to 23.2.1 [\#1342](https://github.com/jrnl-org/jrnl/pull/1342) ([dependabot[bot]](https://github.com/apps/dependabot)) From 44edb9bdee0f0bcd7f8000039c3eeeb3850e9718 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 9 Oct 2021 12:10:08 -0700 Subject: [PATCH 214/215] Add more steps to `pytest`, fully remove `behave` (#1347) * update yaml loader to new method * Add config overrides steps to pytest This requires some patching around the config object, which now happens in every test. Co-authored-by: Micah Jerome Ellison * udpate docs for new tests * remove behave from deps * remove feature dir from flake8 checks * udpate lock file * disable pip version check (it keeps spamming the pipeline) Co-authored-by: Micah Jerome Ellison --- .github/workflows/testing.yaml | 10 +- CONTRIBUTING.md | 4 +- Makefile | 2 +- features/build.feature | 8 - features/core.feature | 21 - features/data/configs/basic_dayone.yaml | 17 - features/data/configs/basic_encrypted.yaml | 17 - features/data/configs/basic_folder.yaml | 17 - features/data/configs/basic_onefile.yaml | 17 - features/data/configs/brackets.yaml | 12 - features/data/configs/bug153.yaml | 17 - features/data/configs/bug343.yaml | 13 - features/data/configs/bug780.yaml | 12 - features/data/configs/dayone.yaml | 12 - features/data/configs/dayone_empty.yaml | 17 - features/data/configs/deletion.yaml | 12 - features/data/configs/deletion_filters.yaml | 12 - features/data/configs/editor-args.yaml | 12 - features/data/configs/editor.yaml | 12 - .../data/configs/editor_empty_folder.yaml | 12 - features/data/configs/editor_encrypted.yaml | 17 - .../configs/editor_markdown_extension.yaml | 18 - features/data/configs/empty_folder.yaml | 12 - features/data/configs/encrypted.yaml | 12 - features/data/configs/encrypted_old.json | 13 - features/data/configs/encrypted_old.yaml | 11 - features/data/configs/format_md.yaml | 19 - features/data/configs/format_text.yaml | 19 - features/data/configs/invalid_color.yaml | 17 - .../data/configs/little_endian_dates.yaml | 12 - .../data/configs/markdown-headings-335.yaml | 17 - features/data/configs/missing_directory.yaml | 17 - features/data/configs/missing_journal.yaml | 17 - .../data/configs/mostlyreadabledates.yaml | 12 - features/data/configs/multiline-tags.yaml | 17 - features/data/configs/multiline.yaml | 17 - features/data/configs/multiple.yaml | 18 - features/data/configs/no_colors.yaml | 12 - features/data/configs/simple.yaml | 17 - features/data/configs/tags-216.yaml | 17 - features/data/configs/tags-237.yaml | 17 - features/data/configs/tags.yaml | 17 - features/data/configs/unreadabledates.yaml | 17 - features/data/configs/upgrade_from_195.json | 11 - .../upgrade_from_195_little_endian_dates.json | 11 - ...om_195_with_missing_encrypted_journal.json | 11 - ...upgrade_from_195_with_missing_journal.json | 11 - .../D04D335AFED711EABA18FAFFC2100C3D.doentry | 53 -- .../FC8A86CAFED711EA8892FAFFC2100C3D.doentry | 55 -- .../FD8ABC8EFED711EABC35FAFFC2100C3D.doentry | 44 -- .../data/journals/basic_encrypted.journal | 1 - .../data/journals/basic_folder/2020/08/29.txt | 19 - .../data/journals/basic_folder/2020/08/31.txt | 23 - .../data/journals/basic_folder/2020/09/24.txt | 11 - features/data/journals/basic_onefile.journal | 58 -- features/data/journals/brackets.journal | 2 - .../B40EE704E15846DE8D45C44118A4D511.doentry | 56 -- .../B40EE704E15846DE8D45C44118A4D512.doentry | 52 -- .../48A25033B34047C591160A4480197D8B.doentry | 33 - .../044F3747A38546168B572C2E3F217FA2.doentry | 34 - .../0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry | 46 -- .../422BC895507944A291E6FC44FC6B8BFC.doentry | 31 - .../4BB1F46946AD439996C9B59DE7C4DDC1.doentry | 29 - .../dayone_empty.dayone/entries/empty.txt | 1 - features/data/journals/deletion.journal | 5 - .../data/journals/deletion_filters.journal | 14 - features/data/journals/empty_folder/empty | 1 - features/data/journals/encrypted.journal | 1 - .../journals/encrypted_jrnl-1-9-5.journal | Bin 128 -> 0 bytes .../data/journals/little_endian_dates.journal | 5 - .../journals/markdown-headings-335.journal | 42 -- .../data/journals/mostlyreadabledates.journal | 8 - features/data/journals/multiline-tags.journal | 7 - features/data/journals/multiline.journal | 5 - features/data/journals/simple.journal | 5 - .../data/journals/simple_jrnl-1-9-5.journal | 13 - ...ple_jrnl-1-9-5_little_endian_dates.journal | 13 - features/data/journals/tags-216.journal | 2 - features/data/journals/tags-237.journal | 3 - features/data/journals/tags.journal | 8 - .../data/journals/unreadabledates.journal | 5 - features/data/journals/work.journal | 0 features/data/templates/extension.md | 0 features/data/templates/sample.template | 19 - features/datetime.feature | 155 ---- features/delete.feature | 229 ------ features/encrypt.feature | 35 - features/environment.py | 86 --- features/file_storage.feature | 56 -- features/format.feature | 621 ---------------- features/import.feature | 93 --- features/multiple_journals.feature | 65 -- features/overrides.feature | 98 --- features/password.feature | 116 --- features/search.feature | 318 -------- features/star.feature | 35 - features/steps/core.py | 687 ------------------ features/steps/export_steps.py | 200 ----- features/steps/override.py | 77 -- features/tag.feature | 53 -- features/upgrade.feature | 71 -- features/write.feature | 216 ------ jrnl/jrnl.py | 4 +- jrnl/override.py | 7 +- poetry.lock | 318 +++----- pyproject.toml | 4 +- tests/bdd/features/override.feature | 19 +- tests/lib/fixtures.py | 7 +- tests/lib/helpers.py | 11 + tests/lib/then_steps.py | 54 +- tests/lib/when_steps.py | 13 + tests/unit/test_override.py | 64 +- 112 files changed, 264 insertions(+), 4814 deletions(-) delete mode 100644 features/build.feature delete mode 100644 features/core.feature delete mode 100644 features/data/configs/basic_dayone.yaml delete mode 100644 features/data/configs/basic_encrypted.yaml delete mode 100644 features/data/configs/basic_folder.yaml delete mode 100644 features/data/configs/basic_onefile.yaml delete mode 100644 features/data/configs/brackets.yaml delete mode 100644 features/data/configs/bug153.yaml delete mode 100644 features/data/configs/bug343.yaml delete mode 100644 features/data/configs/bug780.yaml delete mode 100644 features/data/configs/dayone.yaml delete mode 100644 features/data/configs/dayone_empty.yaml delete mode 100644 features/data/configs/deletion.yaml delete mode 100644 features/data/configs/deletion_filters.yaml delete mode 100644 features/data/configs/editor-args.yaml delete mode 100644 features/data/configs/editor.yaml delete mode 100644 features/data/configs/editor_empty_folder.yaml delete mode 100644 features/data/configs/editor_encrypted.yaml delete mode 100644 features/data/configs/editor_markdown_extension.yaml delete mode 100644 features/data/configs/empty_folder.yaml delete mode 100644 features/data/configs/encrypted.yaml delete mode 100644 features/data/configs/encrypted_old.json delete mode 100644 features/data/configs/encrypted_old.yaml delete mode 100644 features/data/configs/format_md.yaml delete mode 100644 features/data/configs/format_text.yaml delete mode 100644 features/data/configs/invalid_color.yaml delete mode 100644 features/data/configs/little_endian_dates.yaml delete mode 100644 features/data/configs/markdown-headings-335.yaml delete mode 100644 features/data/configs/missing_directory.yaml delete mode 100644 features/data/configs/missing_journal.yaml delete mode 100644 features/data/configs/mostlyreadabledates.yaml delete mode 100644 features/data/configs/multiline-tags.yaml delete mode 100644 features/data/configs/multiline.yaml delete mode 100644 features/data/configs/multiple.yaml delete mode 100644 features/data/configs/no_colors.yaml delete mode 100644 features/data/configs/simple.yaml delete mode 100644 features/data/configs/tags-216.yaml delete mode 100644 features/data/configs/tags-237.yaml delete mode 100644 features/data/configs/tags.yaml delete mode 100644 features/data/configs/unreadabledates.yaml delete mode 100644 features/data/configs/upgrade_from_195.json delete mode 100644 features/data/configs/upgrade_from_195_little_endian_dates.json delete mode 100644 features/data/configs/upgrade_from_195_with_missing_encrypted_journal.json delete mode 100644 features/data/configs/upgrade_from_195_with_missing_journal.json delete mode 100644 features/data/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry delete mode 100644 features/data/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry delete mode 100644 features/data/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry delete mode 100644 features/data/journals/basic_encrypted.journal delete mode 100644 features/data/journals/basic_folder/2020/08/29.txt delete mode 100644 features/data/journals/basic_folder/2020/08/31.txt delete mode 100644 features/data/journals/basic_folder/2020/09/24.txt delete mode 100644 features/data/journals/basic_onefile.journal delete mode 100644 features/data/journals/brackets.journal delete mode 100644 features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry delete mode 100644 features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry delete mode 100644 features/data/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry delete mode 100644 features/data/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry delete mode 100644 features/data/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry delete mode 100644 features/data/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry delete mode 100644 features/data/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry delete mode 100644 features/data/journals/dayone_empty.dayone/entries/empty.txt delete mode 100644 features/data/journals/deletion.journal delete mode 100644 features/data/journals/deletion_filters.journal delete mode 100644 features/data/journals/empty_folder/empty delete mode 100644 features/data/journals/encrypted.journal delete mode 100644 features/data/journals/encrypted_jrnl-1-9-5.journal delete mode 100644 features/data/journals/little_endian_dates.journal delete mode 100644 features/data/journals/markdown-headings-335.journal delete mode 100644 features/data/journals/mostlyreadabledates.journal delete mode 100644 features/data/journals/multiline-tags.journal delete mode 100644 features/data/journals/multiline.journal delete mode 100644 features/data/journals/simple.journal delete mode 100644 features/data/journals/simple_jrnl-1-9-5.journal delete mode 100644 features/data/journals/simple_jrnl-1-9-5_little_endian_dates.journal delete mode 100644 features/data/journals/tags-216.journal delete mode 100644 features/data/journals/tags-237.journal delete mode 100644 features/data/journals/tags.journal delete mode 100644 features/data/journals/unreadabledates.journal delete mode 100644 features/data/journals/work.journal delete mode 100644 features/data/templates/extension.md delete mode 100644 features/data/templates/sample.template delete mode 100644 features/datetime.feature delete mode 100644 features/delete.feature delete mode 100644 features/encrypt.feature delete mode 100644 features/environment.py delete mode 100644 features/file_storage.feature delete mode 100644 features/format.feature delete mode 100644 features/import.feature delete mode 100644 features/multiple_journals.feature delete mode 100644 features/overrides.feature delete mode 100644 features/password.feature delete mode 100644 features/search.feature delete mode 100644 features/star.feature delete mode 100644 features/steps/core.py delete mode 100644 features/steps/export_steps.py delete mode 100644 features/steps/override.py delete mode 100644 features/tag.feature delete mode 100644 features/upgrade.feature delete mode 100644 features/write.feature diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index c6cf4c73..ba999fbe 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -55,7 +55,7 @@ jobs: if: ${{ matrix.python-version != '3.10-dev' }} run: | echo '::group::poetry' - pip install poetry + pip --disable-pip-version-check install poetry poetry config --local virtualenvs.in-project true echo '::endgroup::' @@ -70,7 +70,7 @@ jobs: if: ${{ matrix.python-version == '3.10-dev' }} run: | echo '::group::poetry' - pip install poetry==1.2.0a2 + pip --disable-pip-version-check install poetry==1.2.0a2 poetry config --local virtualenvs.in-project true echo '::endgroup::' @@ -90,12 +90,8 @@ jobs: if: ${{ matrix.python-version != '3.10-dev' && env.DEPS_INSTALLED == 'true' }} run: | poetry run pflake8 --version - poetry run pflake8 jrnl features tests + poetry run pflake8 jrnl tests - name: Test with pytest if: ${{ env.DEPS_INSTALLED == 'true' }} run: poetry run pytest --junitxml=reports/pytest/results.xml - - - name: Test with behave - if: ${{ env.DEPS_INSTALLED == 'true' }} - run: poetry run behave --no-skipped --format progress2 --junit --junit-directory reports/behave diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1f5e691a..cf9c4f36 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -96,9 +96,9 @@ A typical development workflow includes: When resolving bugs or adding new functionality, please add tests to prevent that functionality from breaking in the future. If you notice any functionality that isn't covered in the tests, feel free to submit a test-only pull request as well. -For integration testing, jrnl uses [behave](https://behave.readthedocs.io/) tests, which are all in the `features` folder. +For testing, jrnl uses [pytest](https://docs.pytest.org) for unit tests, and [pytest-bdd](https://pytest-bdd.readthedocs.io/) for integration testing. All tests are in the `tests` folder. -Many tests can be created by only editing `feature` files with the same format as other tests. For more complicated functionality, you may need to implement steps in `features/steps` which are then executed by your tests in the `feature` files. +Many tests can be created by only editing `*.feature` files with the same format as other tests. For more complicated functionality, you may need to implement steps in `tests/lib/` which are then executed by your tests in the `feature` files. Starting in 2020, jrnl is also using [pytest](https://docs.pytest.org/) for unit tests. These tests are in the `tests` folder. diff --git a/Makefile b/Makefile index b2e27f32..a9833c3e 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ bdd: # bdd tests bdd-debug: # bdd tests poetry run pytest tests/bdd --gherkin-terminal-reporter --tb=native -x -vv -test: lint unit bdd ## Run unit tests and behave tests +test: lint unit bdd build: poetry build diff --git a/features/build.feature b/features/build.feature deleted file mode 100644 index 4725ea85..00000000 --- a/features/build.feature +++ /dev/null @@ -1,8 +0,0 @@ -Feature: Build process - - @deployment_tests - Scenario: Version numbers should stay in sync - Given we use the config "simple.yaml" - When we run "jrnl --version" - Then we should get no error - And the output should contain pyproject.toml version diff --git a/features/core.feature b/features/core.feature deleted file mode 100644 index 26640c00..00000000 --- a/features/core.feature +++ /dev/null @@ -1,21 +0,0 @@ -Feature: Functionality of jrnl outside of actually handling journals - - Scenario: Displaying the version number - Given we use the config "simple.yaml" - When we run "jrnl --version" - Then we should get no error - Then the output should match "^jrnl version v\d+\.\d+(\.\d+)?(-(alpha|beta)\d*)?" - - Scenario: Displaying the version number - Given we use the config "simple.yaml" - When we run "jrnl -v" - Then we should get no error - Then the output should match "^jrnl version v\d+\.\d+(\.\d+)?(-(alpha|beta)\d*)?" - - Scenario: Running the diagnostic command - When we run "jrnl --diagnostic" - Then the output should contain "jrnl" - And the output should contain "Python" - - @todo - Scenario: Listing available journals diff --git a/features/data/configs/basic_dayone.yaml b/features/data/configs/basic_dayone.yaml deleted file mode 100644 index 0209f2f7..00000000 --- a/features/data/configs/basic_dayone.yaml +++ /dev/null @@ -1,17 +0,0 @@ -colors: - date: none - title: none - body: none - tags: none -default_hour: 9 -default_minute: 0 -editor: noop -encrypt: false -highlight: true -journals: - default: features/journals/basic_dayone.dayone -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/features/data/configs/basic_encrypted.yaml b/features/data/configs/basic_encrypted.yaml deleted file mode 100644 index 77f4e48d..00000000 --- a/features/data/configs/basic_encrypted.yaml +++ /dev/null @@ -1,17 +0,0 @@ -colors: - date: none - title: none - body: none - tags: none -default_hour: 9 -default_minute: 0 -editor: noop -encrypt: true -highlight: true -journals: - default: features/journals/basic_encrypted.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/features/data/configs/basic_folder.yaml b/features/data/configs/basic_folder.yaml deleted file mode 100644 index ba0de638..00000000 --- a/features/data/configs/basic_folder.yaml +++ /dev/null @@ -1,17 +0,0 @@ -colors: - date: none - title: none - body: none - tags: none -default_hour: 9 -default_minute: 0 -editor: noop -encrypt: false -highlight: true -journals: - default: features/journals/basic_folder -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/features/data/configs/basic_onefile.yaml b/features/data/configs/basic_onefile.yaml deleted file mode 100644 index fb48c6f8..00000000 --- a/features/data/configs/basic_onefile.yaml +++ /dev/null @@ -1,17 +0,0 @@ -colors: - date: none - title: none - body: none - tags: none -default_hour: 9 -default_minute: 0 -editor: noop -encrypt: false -highlight: true -journals: - default: features/journals/basic_onefile.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/features/data/configs/brackets.yaml b/features/data/configs/brackets.yaml deleted file mode 100644 index e658947c..00000000 --- a/features/data/configs/brackets.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/brackets.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/features/data/configs/bug153.yaml b/features/data/configs/bug153.yaml deleted file mode 100644 index ff645ab6..00000000 --- a/features/data/configs/bug153.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: false -highlight: true -journals: - default: features/journals/bug153.dayone -linewrap: 80 -tagsymbols: '@' -template: false -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/features/data/configs/bug343.yaml b/features/data/configs/bug343.yaml deleted file mode 100644 index a4e25d8a..00000000 --- a/features/data/configs/bug343.yaml +++ /dev/null @@ -1,13 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -template: false -encrypt: false -highlight: true -journals: - simple: features/journals/simple.journal - work: features/journals/work.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/features/data/configs/bug780.yaml b/features/data/configs/bug780.yaml deleted file mode 100644 index e1d830c2..00000000 --- a/features/data/configs/bug780.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: false -highlight: true -journals: - default: features/journals/bug780.dayone -linewrap: 80 -tagsymbols: '@' -template: false -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/features/data/configs/dayone.yaml b/features/data/configs/dayone.yaml deleted file mode 100644 index 894cb911..00000000 --- a/features/data/configs/dayone.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: noop -template: false -encrypt: false -highlight: true -journals: - default: features/journals/dayone.dayone -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/features/data/configs/dayone_empty.yaml b/features/data/configs/dayone_empty.yaml deleted file mode 100644 index 7750d389..00000000 --- a/features/data/configs/dayone_empty.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: noop -template: false -encrypt: false -highlight: true -journals: - default: features/journals/dayone_empty.dayone -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/features/data/configs/deletion.yaml b/features/data/configs/deletion.yaml deleted file mode 100644 index d4155260..00000000 --- a/features/data/configs/deletion.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/deletion.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/features/data/configs/deletion_filters.yaml b/features/data/configs/deletion_filters.yaml deleted file mode 100644 index 73a88e4d..00000000 --- a/features/data/configs/deletion_filters.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/deletion_filters.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/features/data/configs/editor-args.yaml b/features/data/configs/editor-args.yaml deleted file mode 100644 index 12c5bd9c..00000000 --- a/features/data/configs/editor-args.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: vim -f -c 'setf markdown' -encrypt: false -highlight: true -journals: - default: features/journals/simple.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/features/data/configs/editor.yaml b/features/data/configs/editor.yaml deleted file mode 100644 index 8a06f916..00000000 --- a/features/data/configs/editor.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "vim" -encrypt: false -highlight: true -journals: - default: features/journals/simple.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/features/data/configs/editor_empty_folder.yaml b/features/data/configs/editor_empty_folder.yaml deleted file mode 100644 index 1724bbfb..00000000 --- a/features/data/configs/editor_empty_folder.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: 'vim' -template: false -encrypt: false -highlight: true -journals: - default: features/journals/empty_folder -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/features/data/configs/editor_encrypted.yaml b/features/data/configs/editor_encrypted.yaml deleted file mode 100644 index 75273c96..00000000 --- a/features/data/configs/editor_encrypted.yaml +++ /dev/null @@ -1,17 +0,0 @@ -colors: - body: green - date: blue - tags: none - title: yellow -default_hour: 9 -default_minute: 0 -editor: "vim" -encrypt: true -template: false -highlight: true -journals: - default: features/journals/encrypted.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/features/data/configs/editor_markdown_extension.yaml b/features/data/configs/editor_markdown_extension.yaml deleted file mode 100644 index bf3b8d8e..00000000 --- a/features/data/configs/editor_markdown_extension.yaml +++ /dev/null @@ -1,18 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -editor: "vim" -journals: - default: features/journals/editor_markdown_extension.journal -linewrap: 80 -tagsymbols: "@" -template: features/templates/extension.md -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/features/data/configs/empty_folder.yaml b/features/data/configs/empty_folder.yaml deleted file mode 100644 index 52a21854..00000000 --- a/features/data/configs/empty_folder.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -template: false -encrypt: false -highlight: true -journals: - default: features/journals/empty_folder -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/features/data/configs/encrypted.yaml b/features/data/configs/encrypted.yaml deleted file mode 100644 index 4d50b607..00000000 --- a/features/data/configs/encrypted.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: true -template: false -highlight: true -journals: - default: features/journals/encrypted.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/features/data/configs/encrypted_old.json b/features/data/configs/encrypted_old.json deleted file mode 100644 index e69d9b79..00000000 --- a/features/data/configs/encrypted_old.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "default_hour": 9, - "default_minute": 0, - "editor": "", - "encrypt": true, - "highlight": true, - "journals": { - "default": "features/journals/encrypted_jrnl-1-9-5.journal" - }, - "linewrap": 80, - "tagsymbols": "@", - "timeformat": "%Y-%m-%d %H:%M" -} diff --git a/features/data/configs/encrypted_old.yaml b/features/data/configs/encrypted_old.yaml deleted file mode 100644 index bc7b1440..00000000 --- a/features/data/configs/encrypted_old.yaml +++ /dev/null @@ -1,11 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: true -highlight: true -journals: - default: features/journals/encrypted_jrnl1-9-5.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/features/data/configs/format_md.yaml b/features/data/configs/format_md.yaml deleted file mode 100644 index 0b9f1c3b..00000000 --- a/features/data/configs/format_md.yaml +++ /dev/null @@ -1,19 +0,0 @@ -colors: - body: none - date: none - tags: none - title: none -default_hour: 9 -default_minute: 0 -display_format: markdown -editor: '' -encrypt: false -highlight: true -indent_character: '|' -journals: - default: features/journals/simple.journal -linewrap: 80 -tagsymbols: '@' -template: false -timeformat: '%Y-%m-%d %H:%M' -version: v2.4.5 diff --git a/features/data/configs/format_text.yaml b/features/data/configs/format_text.yaml deleted file mode 100644 index c82ff7a7..00000000 --- a/features/data/configs/format_text.yaml +++ /dev/null @@ -1,19 +0,0 @@ -colors: - body: none - date: none - tags: none - title: none -default_hour: 9 -default_minute: 0 -display_format: text -editor: '' -encrypt: false -highlight: true -indent_character: '|' -journals: - default: features/journals/simple.journal -linewrap: 80 -tagsymbols: '@' -template: false -timeformat: '%Y-%m-%d %H:%M' -version: v2.4.5 diff --git a/features/data/configs/invalid_color.yaml b/features/data/configs/invalid_color.yaml deleted file mode 100644 index 25c0e58d..00000000 --- a/features/data/configs/invalid_color.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/simple.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" -colors: - date: not-a-color - title: also-not-a-color - body: still-no-color - tags: me-too diff --git a/features/data/configs/little_endian_dates.yaml b/features/data/configs/little_endian_dates.yaml deleted file mode 100644 index 223c820d..00000000 --- a/features/data/configs/little_endian_dates.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/little_endian_dates.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%d.%m.%Y %H:%M" -indent_character: "|" diff --git a/features/data/configs/markdown-headings-335.yaml b/features/data/configs/markdown-headings-335.yaml deleted file mode 100644 index 4368f641..00000000 --- a/features/data/configs/markdown-headings-335.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: false -highlight: true -template: false -journals: - default: features/journals/markdown-headings-335.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/features/data/configs/missing_directory.yaml b/features/data/configs/missing_directory.yaml deleted file mode 100644 index d600404c..00000000 --- a/features/data/configs/missing_directory.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/missing_directory/simple.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/features/data/configs/missing_journal.yaml b/features/data/configs/missing_journal.yaml deleted file mode 100644 index a1f6f8cf..00000000 --- a/features/data/configs/missing_journal.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/missing.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/features/data/configs/mostlyreadabledates.yaml b/features/data/configs/mostlyreadabledates.yaml deleted file mode 100644 index 5e3e1a15..00000000 --- a/features/data/configs/mostlyreadabledates.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/mostlyreadabledates.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/features/data/configs/multiline-tags.yaml b/features/data/configs/multiline-tags.yaml deleted file mode 100644 index 033aaa27..00000000 --- a/features/data/configs/multiline-tags.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/multiline-tags.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/features/data/configs/multiline.yaml b/features/data/configs/multiline.yaml deleted file mode 100644 index aa35b3f5..00000000 --- a/features/data/configs/multiline.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/multiline.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/features/data/configs/multiple.yaml b/features/data/configs/multiple.yaml deleted file mode 100644 index 65f2c256..00000000 --- a/features/data/configs/multiple.yaml +++ /dev/null @@ -1,18 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: false -highlight: true -template: false -journals: - default: features/journals/simple.journal - ideas: features/journals/nothing.journal - simple: features/journals/simple.journal - work: features/journals/work.journal - new_encrypted: - encrypt: true - journal: features/journals/new_encrypted.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" diff --git a/features/data/configs/no_colors.yaml b/features/data/configs/no_colors.yaml deleted file mode 100644 index 9111b561..00000000 --- a/features/data/configs/no_colors.yaml +++ /dev/null @@ -1,12 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/simple.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" diff --git a/features/data/configs/simple.yaml b/features/data/configs/simple.yaml deleted file mode 100644 index 020bab18..00000000 --- a/features/data/configs/simple.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/simple.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/features/data/configs/tags-216.yaml b/features/data/configs/tags-216.yaml deleted file mode 100644 index 81b3865f..00000000 --- a/features/data/configs/tags-216.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: false -highlight: true -template: false -journals: - default: features/journals/tags-216.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/features/data/configs/tags-237.yaml b/features/data/configs/tags-237.yaml deleted file mode 100644 index 5aecd61e..00000000 --- a/features/data/configs/tags-237.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: false -highlight: true -template: false -journals: - default: features/journals/tags-237.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/features/data/configs/tags.yaml b/features/data/configs/tags.yaml deleted file mode 100644 index 4b55952c..00000000 --- a/features/data/configs/tags.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: '' -encrypt: false -highlight: true -template: false -journals: - default: features/journals/tags.journal -linewrap: 80 -tagsymbols: '@' -timeformat: '%Y-%m-%d %H:%M' -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/features/data/configs/unreadabledates.yaml b/features/data/configs/unreadabledates.yaml deleted file mode 100644 index 99304e5a..00000000 --- a/features/data/configs/unreadabledates.yaml +++ /dev/null @@ -1,17 +0,0 @@ -default_hour: 9 -default_minute: 0 -editor: "" -encrypt: false -highlight: true -journals: - default: features/journals/unreadabledates.journal -linewrap: 80 -tagsymbols: "@" -template: false -timeformat: "%Y-%m-%d %H:%M" -indent_character: "|" -colors: - date: none - title: none - body: none - tags: none diff --git a/features/data/configs/upgrade_from_195.json b/features/data/configs/upgrade_from_195.json deleted file mode 100644 index ec380372..00000000 --- a/features/data/configs/upgrade_from_195.json +++ /dev/null @@ -1,11 +0,0 @@ -{ -"default_hour": 9, -"timeformat": "%Y-%m-%d %H:%M", -"linewrap": 80, -"encrypt": false, -"editor": "", -"default_minute": 0, -"highlight": true, -"journals": {"default": "features/journals/simple_jrnl-1-9-5.journal"}, -"tagsymbols": "@" -} diff --git a/features/data/configs/upgrade_from_195_little_endian_dates.json b/features/data/configs/upgrade_from_195_little_endian_dates.json deleted file mode 100644 index 7d3c470c..00000000 --- a/features/data/configs/upgrade_from_195_little_endian_dates.json +++ /dev/null @@ -1,11 +0,0 @@ -{ -"default_hour": 9, -"timeformat": "%d.%m.%Y %H:%M", -"linewrap": 80, -"encrypt": false, -"editor": "", -"default_minute": 0, -"highlight": true, -"journals": {"default": "features/journals/simple_jrnl-1-9-5_little_endian_dates.journal"}, -"tagsymbols": "@" -} diff --git a/features/data/configs/upgrade_from_195_with_missing_encrypted_journal.json b/features/data/configs/upgrade_from_195_with_missing_encrypted_journal.json deleted file mode 100644 index 5bbfb5b1..00000000 --- a/features/data/configs/upgrade_from_195_with_missing_encrypted_journal.json +++ /dev/null @@ -1,11 +0,0 @@ -{ -"default_hour": 9, -"timeformat": "%Y-%m-%d %H:%M", -"linewrap": 80, -"encrypt": true, -"editor": "", -"default_minute": 0, -"highlight": true, -"journals": {"default": "features/journals/encrypted_jrnl-1-9-5.journal", "missing": "features/journals/missing.journal"}, -"tagsymbols": "@" -} diff --git a/features/data/configs/upgrade_from_195_with_missing_journal.json b/features/data/configs/upgrade_from_195_with_missing_journal.json deleted file mode 100644 index 8d456159..00000000 --- a/features/data/configs/upgrade_from_195_with_missing_journal.json +++ /dev/null @@ -1,11 +0,0 @@ -{ -"default_hour": 9, -"timeformat": "%Y-%m-%d %H:%M", -"linewrap": 80, -"encrypt": false, -"editor": "", -"default_minute": 0, -"highlight": true, -"journals": {"default": "features/journals/simple_jrnl-1-9-5.journal", "missing": "features/journals/missing.journal"}, -"tagsymbols": "@" -} diff --git a/features/data/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry b/features/data/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry deleted file mode 100644 index 9721dd55..00000000 --- a/features/data/journals/basic_dayone.dayone/entries/D04D335AFED711EABA18FAFFC2100C3D.doentry +++ /dev/null @@ -1,53 +0,0 @@ - - - - - Creation Date - 2020-08-29T18:11:00Z - Starred - - Entry Text - Entry the first. -Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada -quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque -augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu -consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In -commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget -venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. - -Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo -ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse -potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget -molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus -hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis -feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum -urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget -velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac -porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per -conubia nostra, per inceptos himenaeos. - Time Zone - America/Los_Angeles - UUID - D04D335AFED711EABA18FAFFC2100C3D - Tags - - ipsum - tagone - tagtwo - - Creator - - Device Agent - - Generation Date - 2020-09-25T02:35:45Z - Host Name - iris.lan - OS Agent - Darwin/19.3.0 - Software Agent - jrnl/v2.4.5 - - - diff --git a/features/data/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry b/features/data/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry deleted file mode 100644 index 8c2f3c52..00000000 --- a/features/data/journals/basic_dayone.dayone/entries/FC8A86CAFED711EA8892FAFFC2100C3D.doentry +++ /dev/null @@ -1,55 +0,0 @@ - - - - - Creation Date - 2020-08-31T21:32:00Z - Starred - - Entry Text - A second entry in what I hope to be a long series. -Sed sit amet metus et sapien feugiat elementum. Aliquam bibendum lobortis leo -vitae tempus. Donec eleifend nec mi non volutpat. Lorem ipsum dolor sit amet, -consectetur adipiscing elit. Praesent ut sodales libero. Maecenas nisl lorem, -vestibulum in tempus sit amet, fermentum ut arcu. Donec vel vestibulum lectus, -eget pretium enim. Maecenas diam nunc, imperdiet vitae pharetra sed, pretium id -lectus. Donec eu metus et turpis tempor tristique ac non ex. In tellus arcu, -egestas at efficitur et, ultrices vel est. Sed commodo et nibh non elementum. -Mauris tempus vitae neque vel viverra. @tagtwo all by its lonesome. - -Nulla mattis elementum magna, viverra pretium dui fermentum et. Cras vel -vestibulum odio. Quisque sit amet turpis et urna finibus maximus. Interdum et -malesuada fames ac ante ipsum primis in faucibus. Fusce porttitor iaculis sem, -non dictum ipsum varius nec. Nulla eu erat at risus gravida blandit non vel -ante. Nam egestas ipsum leo, eu ultricies ipsum tincidunt vel. Morbi a commodo -eros. - -Nullam dictum, nisl ac varius tempus, ex tortor fermentum nisl, non -tempus dolor neque a lorem. Suspendisse a faucibus ex, vel ornare tortor. -Maecenas tincidunt id felis quis semper. Pellentesque enim libero, fermentum -quis metus id, rhoncus euismod magna. Nulla finibus velit eu purus bibendum -interdum. Integer id justo dui. Integer eu tellus in turpis bibendum blandit. -Quisque auctor lacinia consectetur. - Time Zone - America/Los_Angeles - UUID - FC8A86CAFED711EA8892FAFFC2100C3D - Tags - - tagtwo - - Creator - - Device Agent - - Generation Date - 2020-09-25T02:36:59Z - Host Name - iris.lan - OS Agent - Darwin/19.3.0 - Software Agent - jrnl/v2.4.5 - - - diff --git a/features/data/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry b/features/data/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry deleted file mode 100644 index d998c36b..00000000 --- a/features/data/journals/basic_dayone.dayone/entries/FD8ABC8EFED711EABC35FAFFC2100C3D.doentry +++ /dev/null @@ -1,44 +0,0 @@ - - - - - Creation Date - 2020-09-24T16:14:00Z - Starred - - Entry Text - The third entry finally after weeks without writing. -I'm so excited about emojis. 💯 🎶 💩 - -Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. -Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla -eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis -dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. -Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis -vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. -Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at -ante eget fringilla. @tagthree and also @tagone - Time Zone - America/Los_Angeles - UUID - FD8ABC8EFED711EABC35FAFFC2100C3D - Tags - - tagthree - tagone - - Creator - - Device Agent - - Generation Date - 2020-09-25T02:37:01Z - Host Name - iris.lan - OS Agent - Darwin/19.3.0 - Software Agent - jrnl/v2.4.5 - - - diff --git a/features/data/journals/basic_encrypted.journal b/features/data/journals/basic_encrypted.journal deleted file mode 100644 index ffc122df..00000000 --- a/features/data/journals/basic_encrypted.journal +++ /dev/null @@ -1 +0,0 @@ -gAAAAABfb4gQBMqqGn_W8v_s7qCi14bX7inuCOKbsBqIUf7_ch14vTUp7lrysPFvhBp5vGijTwDIbk4LKoIISj8NwM31I8L0zEbMx9y6iyF_zseGGNxBvNN0wzAXa67bs-ohiQhhebcdIc_52sltxL2ELh8JAKUaXRwyapgnMgJ7z6deJppLK-B7RE7BiT0eKjWTDMd2x6cZDswvHs9opDp5yjuKWV5m7x6ggCKYgHT3savT9Tg7V0Fq6K3LGWaE59lCrqlAB0u6dnrDX3qcF4SKyckaniXzRShZGebdkUKDcLFun2V2syZwYQN772xjznIsJ16iXicox2uYKg8CnTefsyCwaOZyBvySGEy3CrlBiuIRIcxCtjKbYJ2B-Aq7LZitnBR7Ny_6_Wm8HsBf3N-cFCp4GShiCKrxuXKcOZ7vszG5EKb78JS85bb0mswU5CSdgp6UAHjIZqfJq00qQsViBCbXq3oklCPZXdQkOf5U0KpG2MVUiD-Zcn5Qj3gnUhSEr-5wKU9tWrE63MGPyE6KjZlArZX2W2LeGnW2CEYw9eREGon06AzLJ4mj3BgtjVWLIdGcCwORXvHRjUqazWgbEmXNVTbtp_cKnkW-rFzRBrUoVme9v-1Y3sH0VvHBq7QIj915VzBklzWs1qzIyTPZG5Db9LvdQ7SiV8slf1Jo7l-ayUUdVj6igvKZcgfB4RUHolJoMps5p4lZ5sPqv59KtSa8DCpuoRczIj71OCpuRVARZgy1m5sUD9xSMxOBdy46u1Jnry6iMtzXWI3mEZe5m7UhmW_L4Zcv4bbk8XjkBeHjPdgm2B69jkLmCBFecD5ztoGesCGt_pNo_sWSKqLHV1-coKFB2Nn__a4utU9NJNdeNRkr8_ahU6tn3jmaFjfQ7cKfrXG_NCcYBRX9fja8EQIeBEp_3TCoXQqhuV_bGsNPA2qL63Pt6YiRaUf1g9FNBqJRlKCSOYNixSXQZN_rTePzx0SQ0aIQhADWls62WX-LG5-byJcB6W2P_cH21hDOXkoNEIyLnCz9HQ6Yd6Fbv7298ps3F6jiUDdWES23zv8sDgBuKUN94qSN34j6MDYGFnGI9zsJ-Y-I2frdlLfWPx3pUL7afcKh1nRgXdjctsTSxU2BDrsu03eBz2IoZjoOR0U51IrNMOD1NNT3kctXxHLuOHSEkwAzS3doncQbdRLi5Gc1dQuOUa4sC-p8gVjUKXO-oi_49kp9Km2Ay9wFg0epBbXx2QMzyMsN2dXeSbHF-BDXD6sULaq5syC0fOHqaMLycTCMk2wLfNyXgEt05WvAiDn-LDsRdylMRW2hXp5HWq3Poaul-7VNg6UEMlwVfgJ-7hNreuO6IRtwmx6YdqMscw0ms6mU_MQZU_dTIPg3JU4KL0YyMqPBPSGNCx3gMp41O05Ubir45FoJSnT5Dkj4v3N0S87Ys3HuFLverASsGt9bkcSzd2uMKCJjkspemPPi9VhrY4IOO03DWSWbHmxYzFc1SJ-24WM8Ch404QKpe1qy5LNzFgLvDwQhSIHjluezHXqrD-DVh1lWNNY3WmHI2ubOZfaorvLKqzBPZ6AhpIa60rKjm0OZIQOmJwWXwkdnzut6m8PtoiLzRN897YMgeztf1nmDwp0xE-EhknVZ3WV3TeqgZJ5ykfHQ5BU8x0Db57-UtKSuesKbqPPdBe91OdsPpkGlyl6psHj1_gPm4nLvzXQePwiPaEemR_gYCWGPvl9l1ANJufgCV9qQTmZGof3fb9mjv-9lS-9l_m8KirPPRpSBToNeDtk50ceYUsOlDGzIyusppG9pOcIGyiln1IO5aZ8d4_1E83qjcHTSaKGizICZU7a-pt5STBPMesy3JgBm23A2jO4m68ayBRMcLnw_RirHvvBaj0C6UR2tac45F0Ob3PpXcvFuK0g54ziIAhzGqwF9I-LZ6asXQWMW4y4EBOak8JJBorkfztzfkMaIgGu-4ZoRKOkVfdr4uzcghk3r6KUxD4-nv1ioX69-G5RwhMHppYk7z8RXS1cq5FkvzXbfEQ-Uv6M-sx32DcUy9dH-ZYhc7UWm75JJfiNXLaXT_bsc6VqQ7KPkg2-RA7CywUFCW9S0S-XdO03VdwqlUVo7fp1SKywEfhZv_9bhDCdMJBwZmigv2KP9Iz7fF6LrpLwZkzHuQGFPcyTHFpsVIFrFyJjNYCXpET9y0Q5Vt4fnea5fy-9ZiCt3S8aS0YOFJ35_kM5i3ss8eFPL0v7fIQS3ZilzdGB3bWL0J7kppHN_ekHu-wVk3UZxauoFh7hXLjPcipua-FYUIklLjcK6DG1bYP7_q6OnkC8Jl650FNezeWPomHEv7l_DO3y0tjI6SGdWvL3ZJns7Xp3ew8KsCREAUO7ffqumD03uF9N-9uWbDDjM7rk0vcg0ggfOs9Ni725mxqYpu4R285XCOVWHDvw7iU6eAvE6ry8TDXQBbNgGjTuTYFYYli7GuOqMxFIe1op2s7sRnoJE8O0J76S6APhjhjcnZRSuONWkVG_5o83uFMPSF8DtqLwuRA5E8AGfIwAUcj324sw-DA0ixBGUqomb-osUIisv3x0b044xn-FvD-8R3PZDnPbPsao8XYNxfQWStrNcZSrX2Ua-WAcv9qbQ73_57RKW4pao4ajOu7K5800D231WGiIa6aJzDnFUlzXEzYxFQyx7qegkm_9rrEp_v8TC9mfAcjWX5DMrCkxUskx9YKDfpFYq4NuxO_414gReKzd-lmorfigvttgS10N1XD74SwFluXJv-bqTbI5-SuYAhDGMv1dqrn38i3rOMQqqnQomvaUJRprqxUsKz14sSE1Y-cNqq1FXzZ6vIJq-K3YTfFWPRLeqi6gHzqS_R2YBXXUduKuYgmakiVdP3bWc-Ca8WKh5sVi6P51MO-cS7i9AZWOaOz7F8PsB4JZxAJjSOr3NBmv3EEve9auTFCudRjfC6668I_NMHaTP5CCV4cuhuAxUuKUGgd6WFjDcvoYPyn_lu3bQiqD9MEag4CaJYI9PlraRv5mbqptwxv3pca7usd0GmXN_2No_nwxB4gVb48LsBBkH35njCa5iv2EKXUSOf0k3swaTSEahqbyI4EDzPXtU5uBO39iQzNpgfV_sUpnGdysjqueUVcdWGI_s5CnrNJ-_yDAY06AoXfLrjP8_3NXB2058xZ2rfmTNJNCULz9634dICJReXNnmplxIg3i6GbzFvjfNtqjrWr_iqBShyIwuOUJRbXzdJNggx2BDNG-PEWDXl89SaudFICkDvyZKEcATIss6ZXfULIMfCrqmWmFwgXfNEd9TuvjqoxFlLSaY4UfDMiYa_arUMblFfoo5nV07GANhUoQd-6HRe7LjYeX5VRodOx6ZmZjIAUq-DYr-hatJJFR2tjT_qZht2MJeYT3GZ3o54m8zBBt0JTN7HVpKaOaM3A2hEM_Ah0QZ-DkLDxtCzMuv987GDiLT2-Riya97a47yHIJhZFzFpflW2FcuC8RFWXlfUKTQfZkFmxh3MUekUuS4yu4Z121xojVswk_4P7-FqLaSnGT2epI69I_cvalRx3wjds9-5TFYqf4GridlFBRx6Fv2fpNB9Zvp9k7NQ9oYcPuXGLoXH5kmWBagPhEGKHA_pjFUZmCuwUIoeP4nP8lhFrX8OGezsbSBG773CRJzEdfcgAc5G-p6M_24WZLZHDrsVBAvgrNt6R9eQbEviWU28t_417QCp-or9qqt4OTKv1dp_4MlZh8YBg2-dtpvzSc1l5e4kQFJu7oWlpbgsjB6pl1oRRKp1maedX-gOAf559zC4l85gfEpPln9Cnl6xvERQzfO0Ey4q91SdsgK7i7FBrKKmi2wGiemFvnaQsrjZ_IFujLo8-2c8g9zTiyH1knyoVOAAnQxqGpsz6z6PNfSxr3_G8tOlNFTV-yqN_LdVHMgXtXjn3U9koGsfMulyUcBDdR3d_0Yn6iEjBt77tbxKi2ry-0gQrB1fdGsgKjyE_tMrW8D_lQz0IXsVOzd2ixsFVXMFzD6OOD8JldV0FbA-VDAS-Tp_ezIZVp6lRq54XBgvsjzDyOmOgDbSOQN6SQmvxPnIsml1wgmtm80z-9gHBqmimHBtLKB6L7CtLmmPICMS2pX3eWOmakxscxqs8AVjijJdz_NYNfcdBeDj_fhm6dqD6iwk3EBZZfsrmMGdXtAMqf1r9ng9tsz-FriXwQiJ3IM3loBsk5DKr9CcaJtKSPuwDDlRynD2vwcD-XyF6YTQdSJa9fEcq-qXya2Scj4mqQ4RDemJgErdradRfwJfII3fWHh18XxmYVqi9Bwn3YRgwEadyo0-HjbNq6vJXi12igmP99ciRAfMVQLjfUfTwoOHj44Y2Ru_hPjJcvB6FIn6KLrrCSrZnrshFdFn4L36z1CrS8fbtdvrG3kdZQxsUJnMqttuwKRpLnDWTWkIwj_GRBFrzCFgbwGp1XYhemxggyKVuhZPfyyTIM9rhlPth6eGyrpYfap24Av_mGPRBLnzcjtpGbACGdKQL034kVmI7yENGvmY40KSrWsVG_BE9bSJhx0EptFsT2IxnxbuFD4hGb4fFag9V0BDiKpUoOZqIVqVO8cAp-5w4twvWZKkrhu16JNlLoXWMoFANrw-tp5LKSin1CUeRa4LWVI1GR8tRkIad_GnCHRv9JEMswlNy9wi2sDNsSxWT7WNasUW5-glgK9pR7d2pXGGOWfHj1U6CKIqmAiO3iw8igzhvyx_dAxMxPo \ No newline at end of file diff --git a/features/data/journals/basic_folder/2020/08/29.txt b/features/data/journals/basic_folder/2020/08/29.txt deleted file mode 100644 index c8af54ca..00000000 --- a/features/data/journals/basic_folder/2020/08/29.txt +++ /dev/null @@ -1,19 +0,0 @@ -[2020-08-29 11:11:00 AM] Entry the first. -Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada -quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque -augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu -consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In -commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget -venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. - -Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo -ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse -potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget -molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus -hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis -feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum -urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget -velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac -porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per -conubia nostra, per inceptos himenaeos. diff --git a/features/data/journals/basic_folder/2020/08/31.txt b/features/data/journals/basic_folder/2020/08/31.txt deleted file mode 100644 index 826e7cdb..00000000 --- a/features/data/journals/basic_folder/2020/08/31.txt +++ /dev/null @@ -1,23 +0,0 @@ -[2020-08-31 02:32:00 PM] A second entry in what I hope to be a long series. * -Sed sit amet metus et sapien feugiat elementum. Aliquam bibendum lobortis leo -vitae tempus. Donec eleifend nec mi non volutpat. Lorem ipsum dolor sit amet, -consectetur adipiscing elit. Praesent ut sodales libero. Maecenas nisl lorem, -vestibulum in tempus sit amet, fermentum ut arcu. Donec vel vestibulum lectus, -eget pretium enim. Maecenas diam nunc, imperdiet vitae pharetra sed, pretium id -lectus. Donec eu metus et turpis tempor tristique ac non ex. In tellus arcu, -egestas at efficitur et, ultrices vel est. Sed commodo et nibh non elementum. -Mauris tempus vitae neque vel viverra. @tagtwo all by its lonesome. - -Nulla mattis elementum magna, viverra pretium dui fermentum et. Cras vel -vestibulum odio. Quisque sit amet turpis et urna finibus maximus. Interdum et -malesuada fames ac ante ipsum primis in faucibus. Fusce porttitor iaculis sem, -non dictum ipsum varius nec. Nulla eu erat at risus gravida blandit non vel -ante. Nam egestas ipsum leo, eu ultricies ipsum tincidunt vel. Morbi a commodo -eros. - -Nullam dictum, nisl ac varius tempus, ex tortor fermentum nisl, non -tempus dolor neque a lorem. Suspendisse a faucibus ex, vel ornare tortor. -Maecenas tincidunt id felis quis semper. Pellentesque enim libero, fermentum -quis metus id, rhoncus euismod magna. Nulla finibus velit eu purus bibendum -interdum. Integer id justo dui. Integer eu tellus in turpis bibendum blandit. -Quisque auctor lacinia consectetur. diff --git a/features/data/journals/basic_folder/2020/09/24.txt b/features/data/journals/basic_folder/2020/09/24.txt deleted file mode 100644 index 2bd885ce..00000000 --- a/features/data/journals/basic_folder/2020/09/24.txt +++ /dev/null @@ -1,11 +0,0 @@ -[2020-09-24 09:14:00 AM] The third entry finally after weeks without writing. -I'm so excited about emojis. 💯 🎶 💩 - -Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. -Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla -eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis -dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. -Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis -vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. -Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at -ante eget fringilla. @tagthree and also @tagone diff --git a/features/data/journals/basic_onefile.journal b/features/data/journals/basic_onefile.journal deleted file mode 100644 index 0d988049..00000000 --- a/features/data/journals/basic_onefile.journal +++ /dev/null @@ -1,58 +0,0 @@ -[2020-08-29 11:11] Entry the first. - -Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada -quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque -augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu -consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In -commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget -venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. - -Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo -ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse -potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget -molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus -hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis -feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum -urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget -velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac -porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per -conubia nostra, per inceptos himenaeos. - -[2020-08-31 14:32] A second entry in what I hope to be a long series. * - -Sed sit amet metus et sapien feugiat elementum. Aliquam bibendum lobortis leo -vitae tempus. Donec eleifend nec mi non volutpat. Lorem ipsum dolor sit amet, -consectetur adipiscing elit. Praesent ut sodales libero. Maecenas nisl lorem, -vestibulum in tempus sit amet, fermentum ut arcu. Donec vel vestibulum lectus, -eget pretium enim. Maecenas diam nunc, imperdiet vitae pharetra sed, pretium id -lectus. Donec eu metus et turpis tempor tristique ac non ex. In tellus arcu, -egestas at efficitur et, ultrices vel est. Sed commodo et nibh non elementum. -Mauris tempus vitae neque vel viverra. @tagtwo all by its lonesome. - -Nulla mattis elementum magna, viverra pretium dui fermentum et. Cras vel -vestibulum odio. Quisque sit amet turpis et urna finibus maximus. Interdum et -malesuada fames ac ante ipsum primis in faucibus. Fusce porttitor iaculis sem, -non dictum ipsum varius nec. Nulla eu erat at risus gravida blandit non vel -ante. Nam egestas ipsum leo, eu ultricies ipsum tincidunt vel. Morbi a commodo -eros. - -Nullam dictum, nisl ac varius tempus, ex tortor fermentum nisl, non -tempus dolor neque a lorem. Suspendisse a faucibus ex, vel ornare tortor. -Maecenas tincidunt id felis quis semper. Pellentesque enim libero, fermentum -quis metus id, rhoncus euismod magna. Nulla finibus velit eu purus bibendum -interdum. Integer id justo dui. Integer eu tellus in turpis bibendum blandit. -Quisque auctor lacinia consectetur. - -[2020-09-24 09:14] The third entry finally after weeks without writing. - -I'm so excited about emojis. 💯 🎶 💩 - -Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. -Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla -eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis -dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. -Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis -vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. -Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at -ante eget fringilla. @tagthree and also @tagone diff --git a/features/data/journals/brackets.journal b/features/data/journals/brackets.journal deleted file mode 100644 index 4649ea3e..00000000 --- a/features/data/journals/brackets.journal +++ /dev/null @@ -1,2 +0,0 @@ -[2019-07-08 05:42] Entry subject -[1] line starting with 1 diff --git a/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry b/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry deleted file mode 100644 index 066821bb..00000000 --- a/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D511.doentry +++ /dev/null @@ -1,56 +0,0 @@ - - - - - Creation Date - 2013-10-27T02:27:27Z - Creator - - Device Agent - iPhone/iPhone3,1 - Generation Date - 2013-10-27T07:02:27Z - Host Name - omrt104001 - OS Agent - iOS/7.0.3 - Software Agent - Day One (iOS)/1.11.4 - - Entry Text - Some text. - Location - - Administrative Area - Östergötlands län - Country - Sverige - Latitude - 58.383400000000000 - Locality - City - Longitude - 15.577170000000000 - Place Name - Street - - Starred - - Time Zone - Europe/Stockholm - UUID - B40EE704E15846DE8D45C44118A4D511 - Weather - - Celsius - 12 - Description - Clear - Fahrenheit - 54 - IconName - sunnyn.png - - - diff --git a/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry b/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry deleted file mode 100644 index ea3efec5..00000000 --- a/features/data/journals/bug153.dayone/entries/B40EE704E15846DE8D45C44118A4D512.doentry +++ /dev/null @@ -1,52 +0,0 @@ - - Creation Date - 2013-10-27T02:27:27Z - Creator - - Device Agent - iPhone/iPhone3,1 - Generation Date - 2013-10-27T07:02:27Z - Host Name - omrt104001 - OS Agent - iOS/7.0.3 - Software Agent - Day One (iOS)/1.11.4 - - Entry Text - This is not a valid plist. - Location - - Administrative Area - Östergötlands län - Country - Sverige - Latitude - 58.383400000000000 - Locality - City - Longitude - 15.577170000000000 - Place Name - Street - - Starred - - Time Zone - Europe/Stockholm - UUID - B40EE704E15846DE8D45C44118A4D511 - Weather - - Celsius - 12 - Description - Clear - Fahrenheit - 54 - IconName - sunnyn.png - - - diff --git a/features/data/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry b/features/data/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry deleted file mode 100644 index 426f1ea8..00000000 --- a/features/data/journals/bug780.dayone/entries/48A25033B34047C591160A4480197D8B.doentry +++ /dev/null @@ -1,33 +0,0 @@ - - - - - Activity - Stationary - Creation Date - 2019-12-30T21:28:54Z - Entry Text - - Starred - - UUID - 48A25033B34047C591160A4480197D8B - Creator - - Device Agent - PC - Generation Date - 2019-12-30T21:28:54Z - Host Name - LE-TREPORT - OS Agent - Microsoft Windows/10 Home - Software Agent - Journaley/2.1 - - Tags - - i_have_no_body - - - diff --git a/features/data/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry b/features/data/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry deleted file mode 100644 index 1ac26242..00000000 --- a/features/data/journals/dayone.dayone/entries/044F3747A38546168B572C2E3F217FA2.doentry +++ /dev/null @@ -1,34 +0,0 @@ - - - - - Creation Date - 2013-05-17T18:39:20Z - Creator - - Device Agent - Macintosh/MacBookAir5,2 - Generation Date - 2013-08-17T18:39:20Z - Host Name - Egeria - OS Agent - Mac OS X/10.8.4 - Software Agent - Day One (Mac)/1.8 - - Entry Text - This entry has tags! - Starred - - Tags - - work - PLaY - - Time Zone - America/Los_Angeles - UUID - 044F3747A38546168B572C2E3F217FA2 - - diff --git a/features/data/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry b/features/data/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry deleted file mode 100644 index 927de884..00000000 --- a/features/data/journals/dayone.dayone/entries/0BDDD6CDA43C4A9AA2681517CC35AD9D.doentry +++ /dev/null @@ -1,46 +0,0 @@ - - - - - Creation Date - 2013-06-17T18:38:29Z - Creator - - Device Agent - Macintosh/MacBookAir5,2 - Generation Date - 2013-08-17T18:38:29Z - Host Name - Egeria - OS Agent - Mac OS X/10.8.4 - Software Agent - Day One (Mac)/1.8 - - Entry Text - This entry has a location. - Location - - Administrative Area - California - Country - Germany - Latitude - 52.4979764 - Locality - Berlin - Longitude - 13.2404758 - Place Name - Abandoned Spy Tower - - Starred - - Tags - - Time Zone - Europe/Berlin - UUID - 0BDDD6CDA43C4A9AA2681517CC35AD9D - - diff --git a/features/data/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry b/features/data/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry deleted file mode 100644 index 16260763..00000000 --- a/features/data/journals/dayone.dayone/entries/422BC895507944A291E6FC44FC6B8BFC.doentry +++ /dev/null @@ -1,31 +0,0 @@ - - - - - Creation Date - 2013-07-17T18:38:08Z - Creator - - Device Agent - Macintosh/MacBookAir5,2 - Generation Date - 2013-08-17T18:38:08Z - Host Name - Egeria - OS Agent - Mac OS X/10.8.4 - Software Agent - Day One (Mac)/1.8 - - Entry Text - This entry is starred! - Starred - - Tags - - Time Zone - America/Los_Angeles - UUID - 422BC895507944A291E6FC44FC6B8BFC - - diff --git a/features/data/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry b/features/data/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry deleted file mode 100644 index 9ebaf538..00000000 --- a/features/data/journals/dayone.dayone/entries/4BB1F46946AD439996C9B59DE7C4DDC1.doentry +++ /dev/null @@ -1,29 +0,0 @@ - - - - - Creation Date - 2013-01-17T18:37:50Z - Creator - - Device Agent - Macintosh/MacBookAir5,2 - Generation Date - 2013-08-17T18:37:50Z - Host Name - Egeria - OS Agent - Mac OS X/10.8.4 - Software Agent - Day One (Mac)/1.8 - - Entry Text - This is a DayOne entry without Timezone. - Starred - - Tags - - UUID - 4BB1F46946AD439996C9B59DE7C4DDC1 - - diff --git a/features/data/journals/dayone_empty.dayone/entries/empty.txt b/features/data/journals/dayone_empty.dayone/entries/empty.txt deleted file mode 100644 index c86b8f66..00000000 --- a/features/data/journals/dayone_empty.dayone/entries/empty.txt +++ /dev/null @@ -1 +0,0 @@ -This file exists to preserve the directory structure, but should be ignored by jrnl. diff --git a/features/data/journals/deletion.journal b/features/data/journals/deletion.journal deleted file mode 100644 index c0fa689d..00000000 --- a/features/data/journals/deletion.journal +++ /dev/null @@ -1,5 +0,0 @@ -[2019-10-29 11:11] First entry. - -[2019-10-29 11:11] Second entry. - -[2019-10-29 11:13] Third entry. \ No newline at end of file diff --git a/features/data/journals/deletion_filters.journal b/features/data/journals/deletion_filters.journal deleted file mode 100644 index 9a3747db..00000000 --- a/features/data/journals/deletion_filters.journal +++ /dev/null @@ -1,14 +0,0 @@ -[2019-10-01 08:00] It's just another day in October. -Not much to write about. - -[2020-01-01 08:00] Happy New Year! -So this is the New Year. @holidays - -[2020-03-01 08:00] It's just another day in March. -A stick, a stone, it's the end of the road. - -[2020-05-01 09:00] Happy May Day! -@holidays @springtime Several holidays fall on this date. - -[2020-05-02 12:10] Writing tests. * -@springtime They will help prevent bugs. diff --git a/features/data/journals/empty_folder/empty b/features/data/journals/empty_folder/empty deleted file mode 100644 index 175b82b5..00000000 --- a/features/data/journals/empty_folder/empty +++ /dev/null @@ -1 +0,0 @@ -Nothing to see here diff --git a/features/data/journals/encrypted.journal b/features/data/journals/encrypted.journal deleted file mode 100644 index d2a5fcbe..00000000 --- a/features/data/journals/encrypted.journal +++ /dev/null @@ -1 +0,0 @@ -gAAAAABVIHB7tnwKExG7aC5ZbAbBL9SG2oY2GENeoOJ22i1PZigOvCYvrQN3kpsu0KGr7ay5K-_46R5YFlqJvtQ8anPH2FSITsaZy-l5Lz_5quw3rmzhLwAR1tc0icgtR4MEpXEdsuQ7cyb12Xq-JLDrnATs0id5Vow9Ri_tE7Xe4BXgXaySn3aRPwWKoninVxVPVvETY3MXHSUEXV9OZ-pH5kYBLGYbLA== diff --git a/features/data/journals/encrypted_jrnl-1-9-5.journal b/features/data/journals/encrypted_jrnl-1-9-5.journal deleted file mode 100644 index 339b47baf9671f4550efeb9b6a0cfcd5032255d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 128 zcmV-`0Du3(bJIGVsY(mXmoW-2hF&*L`0NbJTYlTUr8*^Qm97}8E^3^1bZ$P^M diff --git a/features/data/journals/little_endian_dates.journal b/features/data/journals/little_endian_dates.journal deleted file mode 100644 index d7492969..00000000 --- a/features/data/journals/little_endian_dates.journal +++ /dev/null @@ -1,5 +0,0 @@ -[09.06.2013 15:39] My first entry. -Everything is alright - -[10.07.2013 15:40] Life is good. -But I'm better. diff --git a/features/data/journals/markdown-headings-335.journal b/features/data/journals/markdown-headings-335.journal deleted file mode 100644 index 30f592ef..00000000 --- a/features/data/journals/markdown-headings-335.journal +++ /dev/null @@ -1,42 +0,0 @@ -[2015-04-14 13:23] Heading Test - -H1-1 -= - -H1-2 -=== - -H1-3 -============================ - -H2-1 -- - -H2-2 ---- - -H2-3 ----------------------------------- - -Horizontal Rules (ignore) - ---- - -=== - -# ATX H1 - -## ATX H2 - -### ATX H3 - -#### ATX H4 - -##### ATX H5 - -###### ATX H6 - -Stuff - -More stuff -more stuff again diff --git a/features/data/journals/mostlyreadabledates.journal b/features/data/journals/mostlyreadabledates.journal deleted file mode 100644 index bd211bf5..00000000 --- a/features/data/journals/mostlyreadabledates.journal +++ /dev/null @@ -1,8 +0,0 @@ -[2019-07-18 14:23] Entry subject -Time machines are possible. I know, because I've built one in my garage. - -[2019-07-19 14:23] Entry subject -I'm going to activate the machine. Nobody knows what comes next after this. Or before this? - -[2019-07 14:23] Entry subject -I've crossed so many timelines. Is there any going back? diff --git a/features/data/journals/multiline-tags.journal b/features/data/journals/multiline-tags.journal deleted file mode 100644 index 1fb8706f..00000000 --- a/features/data/journals/multiline-tags.journal +++ /dev/null @@ -1,7 +0,0 @@ -[2013-06-09 15:39] Multiple @line entry with @tags. -Tag with @punctuation. afterwards -@TagOnLineAloneWithOutPunctuation -@TagOnLineAloneWithPunctuation. -Text before @tag. And After. -@hi. Hello -hi Hello \ No newline at end of file diff --git a/features/data/journals/multiline.journal b/features/data/journals/multiline.journal deleted file mode 100644 index 294ed141..00000000 --- a/features/data/journals/multiline.journal +++ /dev/null @@ -1,5 +0,0 @@ -[2013-06-09 15:39] Multiple line entry. -This is the first line. -This line doesn't have any ending punctuation - -There is a blank line above this. diff --git a/features/data/journals/simple.journal b/features/data/journals/simple.journal deleted file mode 100644 index 8336068e..00000000 --- a/features/data/journals/simple.journal +++ /dev/null @@ -1,5 +0,0 @@ -[2013-06-09 15:39] My first entry. -Everything is alright - -[2013-06-10 15:40] Life is good. -But I'm better. diff --git a/features/data/journals/simple_jrnl-1-9-5.journal b/features/data/journals/simple_jrnl-1-9-5.journal deleted file mode 100644 index 7bb6c5ac..00000000 --- a/features/data/journals/simple_jrnl-1-9-5.journal +++ /dev/null @@ -1,13 +0,0 @@ -2010-06-10 15:00 A life without chocolate is like a bad analogy. - -2013-06-10 15:40 He said "[this] is the best time to be alive". -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada -quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque -augue et venenatis facilisis. - -[2019-08-03 12:55] Some chat log or something - -Suspendisse potenti. Sed dignissim sed nisl eu consequat. Aenean ante ex, -elementum ut interdum et, mattis eget lacus. In commodo nulla nec tellus -placerat, sed ultricies metus bibendum. Duis eget venenatis erat. In at dolor -dui. diff --git a/features/data/journals/simple_jrnl-1-9-5_little_endian_dates.journal b/features/data/journals/simple_jrnl-1-9-5_little_endian_dates.journal deleted file mode 100644 index 328b23f4..00000000 --- a/features/data/journals/simple_jrnl-1-9-5_little_endian_dates.journal +++ /dev/null @@ -1,13 +0,0 @@ -10.06.2010 15:00 A life without chocolate is like a bad analogy. - -10.06.2013 15:40 He said "[this] is the best time to be alive". -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada -quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque -augue et venenatis facilisis. - -[03.08.2019 12:55] Some chat log or something - -Suspendisse potenti. Sed dignissim sed nisl eu consequat. Aenean ante ex, -elementum ut interdum et, mattis eget lacus. In commodo nulla nec tellus -placerat, sed ultricies metus bibendum. Duis eget venenatis erat. In at dolor -dui. diff --git a/features/data/journals/tags-216.journal b/features/data/journals/tags-216.journal deleted file mode 100644 index 08b6d630..00000000 --- a/features/data/journals/tags-216.journal +++ /dev/null @@ -1,2 +0,0 @@ -[2013-06-10 15:40] I programmed for @OS/2. -Almost makes me want to go back to @C++, though. (Still better than @C#). diff --git a/features/data/journals/tags-237.journal b/features/data/journals/tags-237.journal deleted file mode 100644 index be050652..00000000 --- a/features/data/journals/tags-237.journal +++ /dev/null @@ -1,3 +0,0 @@ -[2014-07-22 11:11] This entry has an email. -@Newline tag should show as a tag. -Kyla's @email is kyla@clevelandunderdog.org and Guinness's is guinness@fortheloveofpits.org. diff --git a/features/data/journals/tags.journal b/features/data/journals/tags.journal deleted file mode 100644 index a28f3159..00000000 --- a/features/data/journals/tags.journal +++ /dev/null @@ -1,8 +0,0 @@ -[2013-04-09 15:39] I have an @idea: -(1) write a command line @journal software -(2) ??? -(3) PROFIT! - -[2013-06-10 15:40] I met with @dan. -As alway's he shared his latest @idea on how to rule the world with me. -inst diff --git a/features/data/journals/unreadabledates.journal b/features/data/journals/unreadabledates.journal deleted file mode 100644 index 53ef1d60..00000000 --- a/features/data/journals/unreadabledates.journal +++ /dev/null @@ -1,5 +0,0 @@ -[ashasd7zdskhz7asdkjasd] Entry subject -I've lost track of time. - -[sadfhakjsdf88sdf7sdff] Entry subject -Time has no meaning. diff --git a/features/data/journals/work.journal b/features/data/journals/work.journal deleted file mode 100644 index e69de29b..00000000 diff --git a/features/data/templates/extension.md b/features/data/templates/extension.md deleted file mode 100644 index e69de29b..00000000 diff --git a/features/data/templates/sample.template b/features/data/templates/sample.template deleted file mode 100644 index a356d823..00000000 --- a/features/data/templates/sample.template +++ /dev/null @@ -1,19 +0,0 @@ ---- -extension: txt ---- - -{% block journal %} -{% for entry in entries %} -{% include entry %} -{% endfor %} - -{% endblock %} - -{% block entry %} -{{ entry.title }} -{{ "-" * len(entry.title) }} - -{{ entry.body }} - -{% endblock %} -` diff --git a/features/datetime.feature b/features/datetime.feature deleted file mode 100644 index 8fe335c9..00000000 --- a/features/datetime.feature +++ /dev/null @@ -1,155 +0,0 @@ -Feature: Reading and writing to journal with custom date formats - - Scenario: Dates can include a time - # https://github.com/jrnl-org/jrnl/issues/117 - Given we use the config "simple.yaml" - When we run "jrnl 2013-11-30 15:42: Project Started." - Then we should see the message "Entry added" - And the journal should contain "[2013-11-30 15:42] Project Started." - - Scenario: Dates can be in the future - # https://github.com/jrnl-org/jrnl/issues/185 - Given we use the config "simple.yaml" - When we run "jrnl 26/06/2099: Planet? Earth. Year? 2099." - Then we should see the message "Entry added" - And the journal should contain "[2099-06-26 09:00] Planet?" - - Scenario: Loading a sample journal with custom date - Given we use the config "little_endian_dates.yaml" - When we run "jrnl -n 2" - Then we should get no error - And the output should be - """ - 09.06.2013 15:39 My first entry. - | Everything is alright - - 10.07.2013 15:40 Life is good. - | But I'm better. - """ - - Scenario Outline: Writing an entry from command line with custom date - Given we use the config ".yaml" - When we run "jrnl " - Then we should see the message "Entry added" - When we run "jrnl -n 1" - Then the output should contain "" - - Examples: Day-first Dates - | config | input | output | - | little_endian_dates | 2020-09-19: My first entry. | 19.09.2020 09:00 My first entry. | - | little_endian_dates | 2020-08-09: My second entry. | 09.08.2020 09:00 My second entry. | - | little_endian_dates | 2020-02-29: Test. | 29.02.2020 09:00 Test. | - | little_endian_dates | 2019-02-29: Test. | 2019-02-29: Test. | - | little_endian_dates | 2020-08-32: Test. | 2020-08-32: Test. | - | little_endian_dates | 2032-02-01: Test. | 01.02.2032 09:00 Test. | - | little_endian_dates | 2020-01-01: Test. | 01.01.2020 09:00 Test. | - | little_endian_dates | 2020-12-31: Test. | 31.12.2020 09:00 Test. | - - Scenario Outline: Searching for dates with custom date - Given we use the config ".yaml" - When we run "jrnl -on '' --short" - Then the output should be "" - - Examples: Day-first Dates - | config | input | output | - | little_endian_dates | 2013-07-10 | 10.07.2013 15:40 Life is good. | - | little_endian_dates | june 9 2013 | 09.06.2013 15:39 My first entry. | - | little_endian_dates | july 10 2013 | 10.07.2013 15:40 Life is good. | - | little_endian_dates | june 2013 | 09.06.2013 15:39 My first entry. | - | little_endian_dates | july 2013 | 10.07.2013 15:40 Life is good. | - # @todo month alone with no year should work - # | little_endian_dates | june | 09.06.2013 15:39 My first entry. | - # | little_endian_dates | july | 10.07.2013 15:40 Life is good. | - - Scenario: Writing an entry at the prompt with custom date - Given we use the config "little_endian_dates.yaml" - When we run "jrnl" and enter "2013-05-10: I saw Elvis. He's alive." - Then we should get no error - And the journal should contain "[10.05.2013 09:00] I saw Elvis." - And the journal should contain "He's alive." - - Scenario: Viewing today's entries does not print the entire journal - # https://github.com/jrnl-org/jrnl/issues/741 - Given we use the config "simple.yaml" - When we run "jrnl -on today" - Then the output should not contain "Life is good" - And the output should not contain "But I'm better." - - Scenario Outline: Create entry using day of the week as entry date. - Given we use the config "simple.yaml" - When we run "jrnl : This is an entry on a ." - Then we should see the message "Entry added" - When we run "jrnl -1" - Then the output should contain " at 9am" in the local time - And the output should contain "This is an entry on a ." - - Examples: Days of the week - | day | - | Monday | - | Tuesday | - | Wednesday | - | Thursday | - | Friday | - | Saturday | - | Sunday | - | sunday | - | sUndAy | - - Scenario Outline: Create entry using day of the week abbreviations as entry date. - Given we use the config "simple.yaml" - When we run "jrnl : This is an entry on a ." - Then we should see the message "Entry added" - When we run "jrnl -1" - Then the output should contain " at 9am" in the local time - - Examples: Days of the week - | day | weekday | - | mon | Monday | - | tue | Tuesday | - | wed | Wednesday | - | thu | Thursday | - | fri | Friday | - | sat | Saturday | - | sun | Sunday | - - Scenario: Journals with unreadable dates should still be loaded - Given we use the config "unreadabledates.yaml" - When we run "jrnl -2" - Then the output should contain "I've lost track of time." - And the output should contain "Time has no meaning." - - Scenario: Journals with readable dates AND unreadable dates should still contain all data. - Given we use the config "mostlyreadabledates.yaml" - When we run "jrnl -3" - Then the output should contain "Time machines are possible." - Then the output should contain "I'm going to activate the machine." - And the output should contain "I've crossed so many timelines. Is there any going back?" - And the journal should have 3 entries - - Scenario: Update near-valid dates after journal is edited - Given we use the config "mostlyreadabledates.yaml" - When we run "jrnl 2222-08-19: I have made it exactly one month into the future." - Then the journal should contain "[2019-07-01 14:23] Entry subject" - - Scenario: Integers in square brackets should not be read as dates - Given we use the config "brackets.yaml" - When we run "jrnl -1" - Then the output should contain "[1] line starting with 1" - - # broken still - @skip - Scenario: Dayone entries without timezone information are interpreted in current timezone - Given we use the config "dayone.yaml" - When we run "jrnl -until 'feb 2013'" - Then we should get no error - And the output should contain "2013-01-17T18:37Z" in the local time - - Scenario: Loading entry with ambiguous time stamp in timezone-aware journal (like Dayone) - #https://github.com/jrnl-org/jrnl/issues/153 - Given we use the config "bug153.yaml" - When we run "jrnl -1" - Then we should get no error - And the output should be - """ - 2013-10-27 03:27 Some text. - """ diff --git a/features/delete.feature b/features/delete.feature deleted file mode 100644 index 2fc3f8f7..00000000 --- a/features/delete.feature +++ /dev/null @@ -1,229 +0,0 @@ -Feature: Delete entries from journal - Scenario Outline: Delete flag allows deletion of single entry - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl -1" - Then the output should contain "2020-09-24 09:14 The third entry finally" - When we run "jrnl --delete" and enter - """ - N - N - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-29 11:11 Entry the first. - 2020-08-31 14:32 A second entry in what I hope to be a long series. - """ - - Examples: Configs - | config | - | basic_onefile | - | basic_encrypted | - # | basic_folder | @todo - # | basic_dayone | @todo - - Scenario Outline: Backing out of interactive delete does not change journal - Given we use the config ".yaml" - When we run "jrnl --delete -n 1" and enter - """ - N - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-29 11:11 Entry the first. - 2020-08-31 14:32 A second entry in what I hope to be a long series. - 2020-09-24 09:14 The third entry finally after weeks without writing. - """ - - Examples: Configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | - - - Scenario Outline: Delete flag with nonsense input deletes nothing (issue #932) - Given we use the config ".yaml" - When we run "jrnl --delete asdfasdf" - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-29 11:11 Entry the first. - 2020-08-31 14:32 A second entry in what I hope to be a long series. - 2020-09-24 09:14 The third entry finally after weeks without writing. - """ - - Examples: Configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | - - Scenario Outline: Delete flag with tag only deletes tagged entries - Given we use the config ".yaml" - When we run "jrnl --delete @ipsum" and enter - """ - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-31 14:32 A second entry in what I hope to be a long series. - 2020-09-24 09:14 The third entry finally after weeks without writing. - """ - - Examples: Configs - | config | - | basic_onefile | - # | basic_folder | @todo - # | basic_dayone | @todo - - - Scenario Outline: Delete flag with multiple tags deletes all entries matching any of the tags - Given we use the config ".yaml" - When we run "jrnl --delete @ipsum @tagthree" and enter - """ - Y - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-31 14:32 A second entry in what I hope to be a long series. - """ - - Examples: Configs - | config | - | basic_onefile | - # | basic_folder | @todo - # | basic_dayone | @todo - - Scenario Outline: Delete flag with -and deletes boolean AND of tagged entries - Given we use the config ".yaml" - When we run "jrnl --delete -and @tagone @tagtwo" and enter - """ - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-31 14:32 A second entry in what I hope to be a long series. - 2020-09-24 09:14 The third entry finally after weeks without writing. - """ - - Examples: Configs - | config | - | basic_onefile | - # | basic_folder | @todo - # | basic_dayone | @todo - - Scenario Outline: Delete flag with -not does not delete entries from given tag - Given we use the config ".yaml" - When we run "jrnl --delete @tagone -not @ipsum" and enter - """ - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-29 11:11 Entry the first. - 2020-08-31 14:32 A second entry in what I hope to be a long series. - """ - - Examples: Configs - | config | - | basic_onefile | - # | basic_folder | @todo - # | basic_dayone | @todo - - Scenario Outline: Delete flag with -from search operator only deletes entries since that date - Given we use the config ".yaml" - When we run "jrnl --delete -from 2020-09-01" and enter - """ - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-29 11:11 Entry the first. - 2020-08-31 14:32 A second entry in what I hope to be a long series. - """ - - Examples: Configs - | config | - | basic_onefile | - # | basic_folder | @todo - # | basic_dayone | @todo - - Scenario Outline: Delete flag with -to only deletes entries up to specified date - Given we use the config ".yaml" - When we run "jrnl --delete -to 2020-08-31" and enter - """ - Y - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-09-24 09:14 The third entry finally after weeks without writing. - """ - - Examples: Configs - | config | - | basic_onefile | - # | basic_folder | @todo - # | basic_dayone | @todo - - - Scenario Outline: Delete flag with -starred only deletes starred entries - Given we use the config ".yaml" - When we run "jrnl --delete -starred" and enter - """ - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-29 11:11 Entry the first. - 2020-09-24 09:14 The third entry finally after weeks without writing. - """ - - Examples: Configs - | config | - | basic_onefile | - # | basic_folder | @todo - # | basic_dayone | @todo - - Scenario Outline: Delete flag with -contains only entries containing expression - Given we use the config ".yaml" - When we run "jrnl --delete -contains dignissim" and enter - """ - Y - """ - Then we flush the output - When we run "jrnl -99 --short" - Then the output should be - """ - 2020-08-31 14:32 A second entry in what I hope to be a long series. - 2020-09-24 09:14 The third entry finally after weeks without writing. - """ - - Examples: Configs - | config | - | basic_onefile | - # | basic_folder | @todo - # | basic_dayone | @todo - diff --git a/features/encrypt.feature b/features/encrypt.feature deleted file mode 100644 index f2d0a62f..00000000 --- a/features/encrypt.feature +++ /dev/null @@ -1,35 +0,0 @@ -Feature: Encrypting and decrypting journals - - Scenario: Decrypting a journal - Given we use the config "encrypted.yaml" - When we run "jrnl --decrypt" and enter "bad doggie no biscuit" - Then the config for journal "default" should have "encrypt" set to "bool:False" - And we should see the message "Journal decrypted" - And the journal should have 2 entries - - @todo - Scenario: Trying to decrypt an already unencrypted journal - # This should warn the user that the journal is already encrypted - Given we use the config "simple.yaml" - When we run "jrnl --decrypt" - Then the config for journal "default" should have "encrypt" set to "bool:False" - And the journal should have 2 entries - - @todo - Scenario: Trying to encrypt an already encrypted journal - # This should warn the user that the journal is already encrypted - - Scenario: 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" - And the config for journal "default" should have "encrypt" set to "bool: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" - diff --git a/features/environment.py b/features/environment.py deleted file mode 100644 index f4baab34..00000000 --- a/features/environment.py +++ /dev/null @@ -1,86 +0,0 @@ -import os -import shutil - -from jrnl.os_compat import on_windows - -CWD = os.getcwd() - -# @see https://behave.readthedocs.io/en/latest/tutorial.html#debug-on-error-in-case-of-step-failures -BEHAVE_DEBUG_ON_ERROR = False - - -def setup_debug_on_error(userdata): - global BEHAVE_DEBUG_ON_ERROR - BEHAVE_DEBUG_ON_ERROR = userdata.getbool("BEHAVE_DEBUG_ON_ERROR") - - -def before_all(context): - setup_debug_on_error(context.config.userdata) - - -# def after_step(context, step): -# if BEHAVE_DEBUG_ON_ERROR and step.status == "failed": -# -- ENTER DEBUGGER: Zoom in on failure location. -# NOTE: Use IPython debugger, same for pdb (basic python debugger). -# import ipdb -# ipdb.post_mortem(step.exc_traceback) - - -def clean_all_working_dirs(): - if os.path.exists("test.txt"): - os.remove("test.txt") - for folder in ("configs", "journals", "cache"): - working_dir = os.path.join("features", folder) - if os.path.exists(working_dir): - shutil.rmtree(working_dir) - - -def before_feature(context, feature): - # add "skip" tag - # https://stackoverflow.com/a/42721605/4276230 - if "skip" in feature.tags: - feature.skip() - return - - if "skip_win" in feature.tags and on_windows(): - feature.skip("Skipping on Windows") - return - - -def before_scenario(context, scenario): - """Before each scenario, backup all config and journal test data.""" - # Clean up in case something went wrong - clean_all_working_dirs() - for folder in ("configs", "journals"): - original = os.path.join("features", "data", folder) - working_dir = os.path.join("features", folder) - if not os.path.exists(working_dir): - os.mkdir(working_dir) - for filename in os.listdir(original): - source = os.path.join(original, filename) - if os.path.isdir(source): - shutil.copytree(source, os.path.join(working_dir, filename)) - else: - shutil.copy2(source, working_dir) - - # add "skip" tag - # https://stackoverflow.com/a/42721605/4276230 - if "skip" in scenario.effective_tags: - scenario.skip() - return - - if "skip_win" in scenario.effective_tags and on_windows(): - scenario.skip("Skipping on Windows") - return - - -def after_scenario(context, scenario): - """After each scenario, restore all test data and remove working_dirs.""" - if os.getcwd() != CWD: - os.chdir(CWD) - - # only clean up if debugging is off and the scenario passed - if BEHAVE_DEBUG_ON_ERROR and scenario.status != "failed": - clean_all_working_dirs() - else: - clean_all_working_dirs() diff --git a/features/file_storage.feature b/features/file_storage.feature deleted file mode 100644 index 33619365..00000000 --- a/features/file_storage.feature +++ /dev/null @@ -1,56 +0,0 @@ -Feature: Journals iteracting with the file system in a way that users can see - - Scenario: Adding entries to a Folder journal should generate date files - Given we use the config "empty_folder.yaml" - When we run "jrnl 23 July 2013: Testing folder journal." - Then we should see the message "Entry added" - When the journal directory is listed - Then the output should contain "2013/07/23.txt" or "2013\07\23.txt" - - Scenario: Adding multiple entries to a Folder journal should generate multiple date files - Given we use the config "empty_folder.yaml" - When we run "jrnl 23 July 2013: Testing folder journal." - And we run "jrnl 3/7/2014: Second entry of journal." - Then we should see the message "Entry added" - When the journal directory is listed - Then the output should contain "2013/07/23.txt" or "2013\07\23.txt" - Then the output should contain "2014/03/07.txt" or "2014\03\07.txt" - - Scenario: If the journal and its parent directory don't exist, they should be created - Given we use the config "missing_directory.yaml" - Then the journal should not exist - When we run "jrnl This is a new entry in my journal" - Then the journal should exist - When we run "jrnl -n 1" - Then the output should contain "This is a new entry in my journal" - And the journal should have 1 entry - - Scenario: If the journal file doesn't exist, then it should be created - Given we use the config "missing_journal.yaml" - Then the journal should not exist - When we run "jrnl This is a new entry in my journal" - Then the journal should exist - When we run "jrnl -n 1" - Then the output should contain "This is a new entry in my journal" - And the journal should have 1 entry - - Scenario: Creating journal with relative path should update to absolute path - Given we use the config "missingconfig" - When we run "jrnl hello world" and enter - """ - test.txt - n - """ - And we change directory to "features" - And we run "jrnl -n 1" - Then the output should contain "hello world" - - Scenario: the temporary filename suffix should default to ".jrnl" - Given we use the config "editor.yaml" - When we run "jrnl --edit" - Then the temporary filename suffix should be ".jrnl" - - Scenario: the temporary filename suffix should be "-{template_filename}" - Given we use the config "editor_markdown_extension.yaml" - When we run "jrnl --edit" - Then the temporary filename suffix should be "-extension.md" diff --git a/features/format.feature b/features/format.feature deleted file mode 100644 index f935e8c8..00000000 --- a/features/format.feature +++ /dev/null @@ -1,621 +0,0 @@ -Feature: Custom formats - - Scenario Outline: Short printing via --format flag - Given We use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl --format short -3" - Then we should get no error - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario Outline: Pretty Printing aka the Default - Given We use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl --format pretty -3" - Then we should get no error - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario Outline: JSON format - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl --format json" - Then we should get no error - And the output should be parsable as json - And "entries" in the json output should have 3 elements - And "tags" in the json output should contain "@ipsum" - And "tags" in the json output should contain "@tagone" - And "tags" in the json output should contain "@tagthree" - And "tags" in the json output should contain "@tagtwo" - And entry 1 should have an array "tags" with 3 elements - And entry 2 should have an array "tags" with 1 elements - And entry 3 should have an array "tags" with 2 elements - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario: Exporting dayone to json - Given we use the config "dayone.yaml" - When we run "jrnl --export json" - Then we should get no error - And the output should be parsable as json - And the json output should contain entries.0.uuid = "4BB1F46946AD439996C9B59DE7C4DDC1" - - Scenario Outline: Printing a journal that has multiline entries with tags - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl -n 1 @ipsum" - Then we should get no error - And the output should be - """ - 2020-08-29 11:11 Entry the first. - | Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada - | quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus - | pellentesque - | augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu - | consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In - | commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget - | venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. - | - | Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo - | ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse - | potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget - | molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus - | hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis - | feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum - | urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. - | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget - | velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac - | porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per - | conubia nostra, per inceptos himenaeos. - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario Outline: Exporting using filters should only export parts of the journal - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl -until 'August 2020' --format json" - Then the output should be parsable as json - Then we should get no error - And the output should be parsable as json - And "entries" in the json output should have 2 elements - And "tags" in the json output should contain "@ipsum" - And "tags" in the json output should contain "@tagone" - And "tags" in the json output should contain "@tagtwo" - And entry 1 should have an array "tags" with 3 elements - And entry 2 should have an array "tags" with 1 elements - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario Outline: Exporting using custom templates - Given we use the config ".yaml" - And we load template "sample.template" - And we use the password "test" if prompted - When we run "jrnl -1 --format sample" - Then the output should be - """ - The third entry finally after weeks without writing. - ---------------------------------------------------- - - I'm so excited about emojis. 💯 🎶 💩 - - Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. - Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla - eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis - dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. - Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis - vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. - Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at - ante eget fringilla. @tagthree and also @tagone - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario Outline: Increasing Headings on Markdown export - Given we use the config ".yaml" - And we use the password "test" if prompted - When we open the editor and append - """ - [2020-10-14 13:23] Heading Test - - H1-1 - = - - H1-2 - === - - H1-3 - ============================ - - H2-1 - - - - H2-2 - --- - - H2-3 - ---------------------------------- - - Horizontal Rules (ignore) - - --- - - === - - # ATX H1 - - ## ATX H2 - - ### ATX H3 - - #### ATX H4 - - ##### ATX H5 - - ###### ATX H6 - - Stuff - - More stuff - more stuff again - """ - Then we flush the output - When we run "jrnl -1 --export markdown" - Then the output should be - """ - # 2020 - - ## October - - ### 2020-10-14 13:23 Heading Test - - #### H1-1 - - #### H1-2 - - #### H1-3 - - ##### H2-1 - - ##### H2-2 - - ##### H2-3 - - Horizontal Rules (ignore) - - --- - - === - - #### ATX H1 - - ##### ATX H2 - - ###### ATX H3 - - ####### ATX H4 - - ######## ATX H5 - - ######### ATX H6 - - Stuff - - More stuff - more stuff again - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - # | basic_dayone | @todo - - Scenario Outline: Add a blank line to Markdown export if there isn't one already - # https://github.com/jrnl-org/jrnl/issues/768 - # https://github.com/jrnl-org/jrnl/issues/881 - Given we use the config ".yaml" - And we use the password "test" if prompted - When we open the editor and append - """ - [2020-10-29 11:11] First entry. - [2020-10-29 11:11] Second entry. - [2020-10-29 11:13] Third entry. - """ - Then we flush the output - When we run "jrnl -3 --format markdown" - Then the output should be - """ - # 2020 - - ## October - - ### 2020-10-29 11:11 First entry. - - - ### 2020-10-29 11:11 Second entry. - - - ### 2020-10-29 11:13 Third entry. - - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - # | basic_dayone | @todo - - @skip - Scenario Outline: Exporting to XML - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl --export xml" - Then the output should be a valid XML string - And "entries" node in the xml output should have 3 elements - And "tags" in the xml output should contain ["@ipsum", "@tagone", "@tagtwo", "@tagthree"] - And there should be 10 "tag" elements - - Examples: configs - | config | - # | basic_onefile | @todo - # | basic_encrypted | @todo - # | basic_folder | @todo - # | basic_dayone | @todo - - Scenario: Exporting to XML - Given we use the config "tags.yaml" - And we use the password "test" if prompted - When we run "jrnl --export xml" - Then the output should be a valid XML string - And "entries" node in the xml output should have 2 elements - And "tags" in the xml output should contain ["@idea", "@journal", "@dan"] - And there should be 7 "tag" elements - - Scenario Outline: Exporting tags - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl --export tags" - Then the output should be - """ - @tagtwo : 2 - @tagone : 2 - @tagthree : 1 - @ipsum : 1 - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - - - Scenario Outline: Export fancy with small linewrap - Given we use the config ".yaml" - 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 | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - @todo - Scenario Outline: Exporting fancy - # Needs better emoji support - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl --export fancy" - Then the output should be - """ - ┎──────────────────────────────────────────────────────────────╮2020-08-29 11:11 - ┃ Entry the first. ╘═══════════════╕ - ┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ - ┃ Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada │ - ┃ quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus │ - ┃ pellentesque │ - ┃ augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu │ - ┃ consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In │ - ┃ commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget │ - ┃ venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. │ - ┃ │ - ┃ Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo │ - ┃ ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. │ - ┃ Suspendisse │ - ┃ potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas │ - ┃ eget │ - ┃ molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed │ - ┃ lectus │ - ┃ hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis │ - ┃ feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, │ - ┃ vestibulum │ - ┃ urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod │ - ┃ enim. │ - ┃ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget │ - ┃ velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac │ - ┃ porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per │ - ┃ conubia nostra, per inceptos himenaeos. │ - ┖──────────────────────────────────────────────────────────────────────────────┘ - ┎──────────────────────────────────────────────────────────────╮2020-08-31 14:32 - ┃ A second entry in what I hope to be a long series. ╘═══════════════╕ - ┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ - ┃ Sed sit amet metus et sapien feugiat elementum. Aliquam bibendum lobortis │ - ┃ leo │ - ┃ vitae tempus. Donec eleifend nec mi non volutpat. Lorem ipsum dolor sit │ - ┃ amet, │ - ┃ consectetur adipiscing elit. Praesent ut sodales libero. Maecenas nisl │ - ┃ lorem, │ - ┃ vestibulum in tempus sit amet, fermentum ut arcu. Donec vel vestibulum │ - ┃ lectus, │ - ┃ eget pretium enim. Maecenas diam nunc, imperdiet vitae pharetra sed, pretium │ - ┃ id │ - ┃ lectus. Donec eu metus et turpis tempor tristique ac non ex. In tellus arcu, │ - ┃ egestas at efficitur et, ultrices vel est. Sed commodo et nibh non │ - ┃ elementum. │ - ┃ Mauris tempus vitae neque vel viverra. @tagtwo all by its lonesome. │ - ┃ │ - ┃ Nulla mattis elementum magna, viverra pretium dui fermentum et. Cras vel │ - ┃ vestibulum odio. Quisque sit amet turpis et urna finibus maximus. Interdum │ - ┃ et │ - ┃ malesuada fames ac ante ipsum primis in faucibus. Fusce porttitor iaculis │ - ┃ sem, │ - ┃ non dictum ipsum varius nec. Nulla eu erat at risus gravida blandit non vel │ - ┃ ante. Nam egestas ipsum leo, eu ultricies ipsum tincidunt vel. Morbi a │ - ┃ commodo │ - ┃ eros. │ - ┃ │ - ┃ Nullam dictum, nisl ac varius tempus, ex tortor fermentum nisl, non │ - ┃ tempus dolor neque a lorem. Suspendisse a faucibus ex, vel ornare tortor. │ - ┃ Maecenas tincidunt id felis quis semper. Pellentesque enim libero, fermentum │ - ┃ quis metus id, rhoncus euismod magna. Nulla finibus velit eu purus bibendum │ - ┃ interdum. Integer id justo dui. Integer eu tellus in turpis bibendum │ - ┃ blandit. │ - ┃ Quisque auctor lacinia consectetur. │ - ┖──────────────────────────────────────────────────────────────────────────────┘ - ┎──────────────────────────────────────────────────────────────╮2020-09-24 09:14 - ┃ The third entry finally after weeks without writing. ╘═══════════════╕ - ┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ - ┃ I'm so excited about emojis. 💯 🎶 💩 │ - ┃ │ - ┃ Donec semper pellentesque iaculis. Nullam cursus et justo sit amet │ - ┃ venenatis. │ - ┃ Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. │ - ┃ Nulla │ - ┃ eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis │ - ┃ dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh │ - ┃ malesuada. │ - ┃ Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis │ - ┃ vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan │ - ┃ justo. │ - ┃ Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at │ - ┃ ante eget fringilla. @tagthree and also @tagone │ - ┖──────────────────────────────────────────────────────────────────────────────┘ - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - @skip_win - Scenario Outline: Export to yaml - Given we use the config ".yaml" - And we use the password "test" if prompted - And we create a cache directory - When we run "jrnl --export yaml -o {cache_dir}" - Then the cache should contain the files - """ - 2020-08-29_entry-the-first.md - 2020-08-31_a-second-entry-in-what-i-hope-to-be-a-long-series.md - 2020-09-24_the-third-entry-finally-after-weeks-without-writing.md - """ - And the content of file "2020-08-29_entry-the-first.md" in the cache should be - """ - --- - title: Entry the first. - date: 2020-08-29 11:11 - starred: False - tags: tagone, ipsum, tagtwo - body: | - Lorem @ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada - quis est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque - augue et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu - consequat. Aenean ante ex, elementum ut interdum et, mattis eget lacus. In - commodo nulla nec tellus placerat, sed ultricies metus bibendum. Duis eget - venenatis erat. In at dolor dui. @tagone and maybe also @tagtwo. - - Curabitur accumsan nunc ac neque tristique, eleifend faucibus justo - ullamcorper. Suspendisse at mattis nunc. Nullam eget lacinia urna. Suspendisse - potenti. Ut urna est, venenatis sed ante in, ultrices congue mi. Maecenas eget - molestie metus. Mauris porttitor dui ornare gravida porta. Quisque sed lectus - hendrerit, lacinia ante eget, vulputate ante. Aliquam vitae erat non felis - feugiat sagittis. Phasellus quis arcu fringilla, mattis ligula id, vestibulum - urna. Vivamus facilisis leo a mi tincidunt condimentum. Donec eu euismod enim. - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu ligula eget - velit scelerisque fringilla. Phasellus pharetra justo et nulla fringilla, ac - porta sapien accumsan. Class aptent taciti sociosqu ad litora torquent per - conubia nostra, per inceptos himenaeos. - ... - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - # | basic_dayone | - - @skip_win # @todo YAML exporter does not correctly export emoji on Windows - Scenario Outline: Add a blank line to YAML export if there isn't one already - # https://github.com/jrnl-org/jrnl/issues/768 - # https://github.com/jrnl-org/jrnl/issues/881 - Given we use the config ".yaml" - And we use the password "test" if prompted - And we create a cache directory - When we run "jrnl --export yaml -o {cache_dir}" - Then the cache should contain the files - """ - 2020-08-29_entry-the-first.md - 2020-08-31_a-second-entry-in-what-i-hope-to-be-a-long-series.md - 2020-09-24_the-third-entry-finally-after-weeks-without-writing.md - """ - And the content of file "2020-09-24_the-third-entry-finally-after-weeks-without-writing.md" in the cache should be - """ - --- - title: The third entry finally after weeks without writing. - date: 2020-09-24 09:14 - starred: False - tags: tagone, tagthree - body: | - I'm so excited about emojis. 💯 🎶 💩 - - Donec semper pellentesque iaculis. Nullam cursus et justo sit amet venenatis. - Vivamus tempus ex dictum metus vehicula gravida. Aliquam sed sem dolor. Nulla - eget ultrices purus. Quisque at nunc at quam pharetra consectetur vitae quis - dolor. Fusce ultricies purus eu est feugiat, quis scelerisque nibh malesuada. - Quisque egestas semper nibh in hendrerit. Nam finibus ex in mi mattis - vulputate. Sed mauris urna, consectetur in justo eu, volutpat accumsan justo. - Phasellus aliquam lacus placerat convallis vestibulum. Curabitur maximus at - ante eget fringilla. @tagthree and also @tagone - ... - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - # | basic_dayone | @todo - - Scenario: Empty DayOne entry bodies should not error - # https://github.com/jrnl-org/jrnl/issues/780 - Given we use the config "bug780.yaml" - When we run "jrnl --short" - Then we should get no error - - Scenario Outline: --short displays the short version of entries (only the title) - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl -on 2020-08-31 --short" - Then the output should be "2020-08-31 14:32 A second entry in what I hope to be a long series." - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario Outline: -s displays the short version of entries (only the title) - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl -on 2020-08-31 -s" - Then the output should be "2020-08-31 14:32 A second entry in what I hope to be a long series." - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario: Markdown Support from config file - Given we use the config "format_md.yaml" - When we run "jrnl -n 1" - Then the output should be - """ - # 2013 - - ## June - - ### 2013-06-10 15:40 Life is good. - - But I'm better. - """ - - Scenario: Text Formatter from config file - Given we use the config "format_text.yaml" - When we run "jrnl -n 1" - Then the output should be - """ - [2013-06-10 15:40] Life is good. - But I'm better. - """ - - Scenario Outline: Exporting entries with Cyrillic characters to directory should not fail - Given we use the config ".yaml" - And we use the password "test" if prompted - And we create a cache directory - When we run "jrnl 2020-11-21: Первая" - When we run "jrnl --format md --file {cache_dir} -on 2020-11-21" - Then the cache should contain the files - """ - 2020-11-21_первая.md - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario Outline: Export date counts - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl 2020-08-31 01:01: Hi." - And we run "jrnl --format dates" - Then the output should be - """ - 2020-08-29, 1 - 2020-08-31, 2 - 2020-09-24, 1 - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | diff --git a/features/import.feature b/features/import.feature deleted file mode 100644 index 63b042fc..00000000 --- a/features/import.feature +++ /dev/null @@ -1,93 +0,0 @@ -Feature: Importing data - - Scenario Outline: --import allows new entry from stdin - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl --import" and pipe "[2020-07-05 15:00] Observe and import." - Then we flush the output - When we run "jrnl -c import" - Then the output should contain "Observe and import" - - Examples: Configs - | config | - | basic_onefile | - | basic_encrypted | - # | basic_folder | @todo - # | basic_dayone | @todo - - Scenario Outline: --import allows new large entry from stdin - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl --import" and pipe - """ - [2020-07-05 15:00] Observe and import. - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent malesuada quis - est ac dignissim. Aliquam dignissim rutrum pretium. Phasellus pellentesque augue - et venenatis facilisis. Suspendisse potenti. Sed dignissim sed nisl eu consequat. - Aenean ante ex, elementum ut interdum et, mattis eget lacus. In commodo nulla nec - tellus placerat, sed ultricies metus bibendum. Duis eget venenatis erat. In at - dolor dui end of entry. - """ - Then we flush the output - When we run "jrnl -on 2020-07-05" - Then the output should contain "2020-07-05 15:00 Observe and import." - And the output should contain "Lorem ipsum" - And the output should contain "end of entry." - - Examples: Configs - | config | - | basic_onefile | - | basic_encrypted | - # | basic_folder | @todo - # | basic_dayone | @todo - - Scenario Outline: --import allows multiple new entries from stdin - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl --import" and pipe - """ - [2020-07-05 15:00] Observe and import. - Lorem ipsum dolor sit amet, consectetur adipiscing elit. - - [2020-07-05 15:01] Twice as nice. - Sed dignissim sed nisl eu consequat. - """ - Then we flush the output - When we run "jrnl -on 2020-07-05" - Then the output should contain "2020-07-05 15:00 Observe and import." - And the output should contain "Lorem ipsum" - And the output should contain "2020-07-05 15:01 Twice as nice." - And the output should contain "Sed dignissim" - - Examples: Configs - | config | - | basic_onefile | - | basic_encrypted | - # | basic_folder | @todo - # | basic_dayone | @todo - - Scenario: --import allows import new entries from file - Given we use the config "simple.yaml" - Then the journal should contain "My first entry." - And the journal should contain "Life is good." - But the journal should not contain "I have an @idea" - And the journal should not contain "I met with" - When we run "jrnl --import --file features/journals/tags.journal" - Then the journal should contain "My first entry." - And the journal should contain "Life is good." - And the journal should contain "PROFIT!" - - Scenario: --import prioritizes --file over pipe data if both are given - Given we use the config "simple.yaml" - Then the journal should contain "My first entry." - And the journal should contain "Life is good." - But the journal should not contain "I have an @idea" - And the journal should not contain "I met with" - When we run "jrnl --import --file features/journals/tags.journal" and pipe - """ - [2020-07-05 15:00] I should not exist! - """ - Then the journal should contain "My first entry." - And the journal should contain "PROFIT!" - But the journal should not contain "I should not exist!" - diff --git a/features/multiple_journals.feature b/features/multiple_journals.feature deleted file mode 100644 index 222be100..00000000 --- a/features/multiple_journals.feature +++ /dev/null @@ -1,65 +0,0 @@ -Feature: Multiple journals - - Scenario: Loading a config with two journals - Given we use the config "multiple.yaml" - Then journal "default" should have 2 entries - And journal "work" should have 0 entries - - Scenario: Write to default config by default - Given we use the config "multiple.yaml" - When we run "jrnl this goes to default" - Then journal "default" should have 3 entries - And journal "work" should have 0 entries - - Scenario: Write to specified journal - Given we use the config "multiple.yaml" - When we run "jrnl work a long day in the office" - Then journal "default" should have 2 entries - And journal "work" should have 1 entry - - Scenario: Tell user which journal was used - Given we use the config "multiple.yaml" - When we run "jrnl work a long day in the office" - Then we should see the message "Entry added to work journal" - - Scenario: Write to specified journal with a timestamp - Given we use the config "multiple.yaml" - When we run "jrnl work 23 july 2012: a long day in the office" - Then journal "default" should have 2 entries - And journal "work" should have 1 entry - And journal "work" should contain "2012-07-23" - - Scenario: Write to specified journal without a timestamp but with colon - Given we use the config "multiple.yaml" - When we run "jrnl work : a long day in the office" - Then journal "default" should have 2 entries - And journal "work" should have 1 entry - And journal "work" should contain "a long day in the office" - - Scenario: Write to specified journal without a timestamp but with colon - Given we use the config "multiple.yaml" - When we run "jrnl work: a long day in the office" - Then journal "default" should have 2 entries - And journal "work" should have 1 entry - And journal "work" should contain "a long day in the office" - - Scenario: Create new journals as required - Given we use the config "multiple.yaml" - Then journal "ideas" should not exist - When we run "jrnl ideas 23 july 2012: sell my junk on ebay and make lots of money" - Then journal "ideas" should have 1 entry - - Scenario: Don't crash if no default journal is specified - Given we use the config "bug343.yaml" - When we run "jrnl a long day in the office" - Then we should see the message "No default journal configured" - - Scenario: Don't crash if no file exists for a configured encrypted journal - Given we use the config "multiple.yaml" - When we run "jrnl new_encrypted Adding first entry" and enter - """ - these three eyes - these three eyes - n - """ - Then we should see the message "Encrypted journal 'new_encrypted' created" diff --git a/features/overrides.feature b/features/overrides.feature deleted file mode 100644 index e0cdd9f0..00000000 --- a/features/overrides.feature +++ /dev/null @@ -1,98 +0,0 @@ -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 - - 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 should have "highlight" set to "bool:false" - And no editor should 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 should have "colors.body" set to "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 should have "colors.body" set to "green" - And the config should have "editor" set to "nano" - - - Scenario Outline: Override configured 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 editor should have been called - Examples: Editor Commands - | editor | - | nano | - | vi -c startinsert | - | code -w | - - Scenario: Override default journal - Given we use the config "basic_dayone.yaml" - And we use the password "test" if prompted - When we run "jrnl --debug --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 --debug --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. - """ diff --git a/features/password.feature b/features/password.feature deleted file mode 100644 index 332ba86e..00000000 --- a/features/password.feature +++ /dev/null @@ -1,116 +0,0 @@ -Feature: Using the installed keyring - - Scenario: Storing a password in keyring - Given we use the config "multiple.yaml" - And we have a keyring - When we run "jrnl simple --encrypt" and enter - """ - sabertooth - sabertooth - y - """ - Then the config for journal "simple" should have "encrypt" set to "bool:True" - When we run "jrnl simple -n 1" - Then the output should contain "2013-06-10 15:40 Life is good" - - Scenario: Encrypt journal with no keyring backend and do not store in keyring - Given we use the config "simple.yaml" - And we do not have a keyring - When we run "jrnl test entry" - And we run "jrnl --encrypt" and enter - """ - password - password - n - """ - Then we should get no error - And we should not see the message "Failed to retrieve keyring" - - Scenario: Encrypt journal with no keyring backend and do store in keyring - Given we use the config "simple.yaml" - And we do not have a keyring - When we run "jrnl test entry" - And we run "jrnl --encrypt" and enter - """ - password - password - y - """ - Then we should get no error - And we should not see the message "Failed to retrieve keyring" - # @todo add step to check contents of keyring - - @todo - Scenario: Open an encrypted journal with wrong password in keyring - # This should ask the user for the password after the keyring fails - - @todo - Scenario: Decrypt journal with password in keyring - - @todo - Scenario: Decrypt journal without a keyring - - Scenario: Encrypt journal when keyring exists but fails - Given we use the config "simple.yaml" - And we have a failed keyring - When we run "jrnl --encrypt" and enter - """ - this password will not be saved in keyring - this password will not be saved in keyring - y - """ - Then we should see the message "Failed to retrieve keyring" - And we should get no error - And we should be prompted for a password - And the config for journal "default" should have "encrypt" set to "bool:True" - - Scenario: Decrypt journal when keyring exists but fails - Given we use the config "encrypted.yaml" - And we have a failed keyring - When we run "jrnl --decrypt" and enter "bad doggie no biscuit" - Then we should see the message "Failed to retrieve keyring" - And we should get no error - And we should be prompted for a password - And we should see the message "Journal decrypted" - And the config for journal "default" should have "encrypt" set to "bool:False" - And the journal should have 2 entries - - Scenario: Open encrypted journal when keyring exists but fails - # This should ask the user for the password after the keyring fails - Given we use the config "encrypted.yaml" - And we have a failed keyring - When we run "jrnl -n 1" and enter "bad doggie no biscuit" - Then we should see the message "Failed to retrieve keyring" - And we should get no error - And we should be prompted for a password - And the output should contain "2013-06-10 15:40 Life is good" - - Scenario: Mistyping your password - Given we use the config "simple.yaml" - When we run "jrnl --encrypt" and enter - """ - swordfish - sordfish - """ - Then we should be prompted for a password - And we should see the message "Passwords did not match" - And the config for journal "default" should not have "encrypt" set - And the journal should have 2 entries - - Scenario: Mistyping your password, then getting it right - Given we use the config "simple.yaml" - When we run "jrnl --encrypt" and enter - """ - swordfish - sordfish - swordfish - swordfish - n - """ - Then we should be prompted for a password - And we should see the message "Passwords did not match" - And we should see the message "Journal encrypted" - And the config for journal "default" should have "encrypt" set to "bool: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" diff --git a/features/search.feature b/features/search.feature deleted file mode 100644 index 22351b7e..00000000 --- a/features/search.feature +++ /dev/null @@ -1,318 +0,0 @@ -Feature: Searching in a journal - - Scenario Outline: Displaying entries using -on today should display entries created today - Given we use the config ".yaml" - When we run "jrnl today: Adding an entry right now." - Then we should see the message "Entry added" - When we run "jrnl -on today" - Then the output should contain "Adding an entry right now." - But the output should not contain "Everything is alright" - And the output should not contain "Life is good" - - Examples: configs - | config | - | simple | - | empty_folder | - | dayone | - - Scenario Outline: Displaying entries using -from day should display correct entries - Given we use the config ".yaml" - When we run "jrnl yesterday: This thing happened yesterday" - Then we should see the message "Entry added" - When we run "jrnl today at 11:59pm: Adding an entry right now." - Then we should see the message "Entry added" - When we run "jrnl tomorrow: A future entry." - Then we should see the message "Entry added" - When we run "jrnl -from today" - Then the output should contain "Adding an entry right now." - And the output should contain "A future entry." - And the output should not contain "This thing happened yesterday" - - Examples: configs - | config | - | simple | - | empty_folder | - | dayone | - - Scenario Outline: Displaying entries using -from and -to day should display correct entries - Given we use the config ".yaml" - When we run "jrnl yesterday: This thing happened yesterday" - Then we should see the message "Entry added" - When we run "jrnl today at 11:59pm: Adding an entry right now." - Then we should see the message "Entry added" - When we run "jrnl tomorrow: A future entry." - Then we should see the message "Entry added" - When we run "jrnl -from yesterday -to today" - Then the output should contain "This thing happened yesterday" - And the output should contain "Adding an entry right now." - And the output should not contain "A future entry." - - Examples: configs - | config | - | simple | - | empty_folder | - | dayone | - - Scenario Outline: Searching for a string - Given we use the config ".yaml" - When we run "jrnl -contains first --short" - Then we should get no error - And the output should be - """ - 2020-08-29 11:11 Entry the first. - """ - - Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | - - Scenario Outline: Searching for a string within tag results - Given we use the config ".yaml" - When we run "jrnl @tagone -contains maybe" - Then we should get no error - And the output should contain "maybe" - - Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | - - Scenario Outline: Searching for a string within AND tag results - Given we use the config ".yaml" - When we run "jrnl -and @tagone @tagtwo -contains maybe" - Then we should get no error - And the output should contain "maybe" - - Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | - - Scenario Outline: Searching for a string within NOT tag results - Given we use the config ".yaml" - When we run "jrnl -not @tagone -contains lonesome" - Then we should get no error - And the output should contain "lonesome" - - Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | - - Scenario Outline: Searching for dates - Given we use the config ".yaml" - When we run "jrnl -on 2020-08-31 --short" - Then the output should be "2020-08-31 14:32 A second entry in what I hope to be a long series." - Then we flush the output - When we run "jrnl -on 'august 31 2020' --short" - Then the output should be "2020-08-31 14:32 A second entry in what I hope to be a long series." - - Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | - - Scenario: Out of order entries to a Folder journal should be listed in date order - Given we use the config "empty_folder.yaml" - When we run "jrnl 3/7/2014 4:37pm: Second entry of journal." - Then we should see the message "Entry added" - When we run "jrnl 23 July 2013: Testing folder journal." - Then we should see the message "Entry added" - When we run "jrnl -2" - Then the output should be - """ - 2013-07-23 09:00 Testing folder journal. - - 2014-03-07 16:37 Second entry of journal. - """ - - Scenario Outline: Searching for all tags should show counts of each tag - Given we use the config ".yaml" - When we run "jrnl --tags" - Then we should get no error - And the output should be - """ - @tagtwo : 2 - @tagone : 2 - @tagthree : 1 - @ipsum : 1 - """ - - Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | - - Scenario Outline: Filtering journals should also filter tags - Given we use the config ".yaml" - When we run "jrnl -from 'september 2020' --tags" - Then we should get no error - And the output should be - """ - @tagthree : 1 - @tagone : 1 - """ - - Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | - - Scenario Outline: Excluding a tag should filter out all entries with that tag - Given we use the config ".yaml" - When we run "jrnl --tags -not @tagtwo" - Then the output should be - """ - @tagthree : 1 - @tagone : 1 - """ - - Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | - - Scenario Outline: Excluding multiple tags should filter out all entries with those tags - Given we use the config ".yaml" - When we run "jrnl --tags -not @tagone -not @tagthree" - Then the output should be - """ - @tagtwo : 1 - """ - - Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | - - Scenario: DayOne tag searching should work with tags containing a mixture of upper and lower case. - # https://github.com/jrnl-org/jrnl/issues/354 - Given we use the config "dayone.yaml" - When we run "jrnl @plAy" - Then the output should contain "2013-05-17 11:39 This entry has tags!" - - Scenario: Loading a sample journal - Given we use the config "simple.yaml" - When we run "jrnl -2" - Then we should get no error - And the output should be - """ - 2013-06-09 15:39 My first entry. - | Everything is alright - - 2013-06-10 15:40 Life is good. - | But I'm better. - """ - - Scenario Outline: Searching by month - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl -month 9 --short" - Then the output should be "2020-09-24 09:14 The third entry finally after weeks without writing." - And we flush the output - When we run "jrnl -month Sept --short" - Then the output should be "2020-09-24 09:14 The third entry finally after weeks without writing." - And we flush the output - When we run "jrnl -month September --short" - Then the output should be "2020-09-24 09:14 The third entry finally after weeks without writing." - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario Outline: Searching by day - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl -day 31 --short" - Then the output should be "2020-08-31 14:32 A second entry in what I hope to be a long series." - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario Outline: Searching by year - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl 2019-01-01 01:01: I like this year." - And we run "jrnl -year 2019 --short" - Then the output should be "2019-01-01 01:01 I like this year." - And we flush the output - When we run "jrnl -year 19 --short" - Then the output should be "2019-01-01 01:01 I like this year." - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario Outline: Combining month, day, and year search terms - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl -month 08 -day 29 --short" - Then the output should be "2020-08-29 11:11 Entry the first." - And we flush the output - When we run "jrnl -day 29 -year 2020 --short" - Then the output should be "2020-08-29 11:11 Entry the first." - And we flush the output - When we run "jrnl -month 09 -year 2020 --short" - Then the output should be "2020-09-24 09:14 The third entry finally after weeks without writing." - And we flush the output - When we run "jrnl -month 08 -day 29 -year 2020 --short" - Then the output should be "2020-08-29 11:11 Entry the first." - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario Outline: Searching today in history - Given we use the config ".yaml" - And we use the password "test" if prompted - And we set current date and time to "2020-08-31 14:32" - When we run "jrnl 2019-08-31 01:01: Hi, from last year." - And we run "jrnl -today-in-history --short" - Then the output should be - """ - 2019-08-31 01:01 Hi, from last year. - 2020-08-31 14:32 A second entry in what I hope to be a long series. - """ - - Examples: configs - | config | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario: Loading a DayOne Journal - Given we use the config "dayone.yaml" - When we run "jrnl -from 'feb 2013'" - Then we should get no error - And the output should be - """ - 2013-05-17 11:39 This entry has tags! - - 2013-06-17 20:38 This entry has a location. - - 2013-07-17 11:38 This entry is starred! - """ diff --git a/features/star.feature b/features/star.feature deleted file mode 100644 index f0188056..00000000 --- a/features/star.feature +++ /dev/null @@ -1,35 +0,0 @@ -Feature: Starring entries - - Scenario Outline: Starring an entry will mark it in the journal file - Given we use the config ".yaml" - When we run "jrnl 20 july 2013 *: Best day of my life!" - Then we should see the message "Entry added" - When we run "jrnl -on 2013-07-20 -starred" - Then the output should contain "2013-07-20 09:00 Best day of my life!" - - Examples: configs - | config_file | - | simple | - | empty_folder | - | dayone | - - Scenario Outline: Filtering by starred entries will show only starred entries - Given we use the config ".yaml" - When we run "jrnl -starred" - Then the output should be empty - When we run "jrnl 20 july 2013 *: Best day of my life!" - When we run "jrnl -starred" - Then the output should be "2013-07-20 09:00 Best day of my life!" - - Examples: configs - | config_file | - | simple | - | empty_folder | - | dayone_empty | - - Scenario: Starring an entry will mark it in an encrypted journal - Given we use the config "encrypted.yaml" - When we run "jrnl 20 july 2013 *: Best day of my life!" and enter "bad doggie no biscuit" - Then we should see the message "Entry added" - When we run "jrnl -on 2013-07-20 -starred" and enter "bad doggie no biscuit" - Then the output should contain "2013-07-20 09:00 Best day of my life!" diff --git a/features/steps/core.py b/features/steps/core.py deleted file mode 100644 index 2ad5bcc4..00000000 --- a/features/steps/core.py +++ /dev/null @@ -1,687 +0,0 @@ -# Copyright (C) 2012-2021 jrnl contributors -# License: https://www.gnu.org/licenses/gpl-3.0.html - -import ast -from collections import defaultdict -from jrnl.args import parse_args -import os -from pathlib import Path -import re -import time -from unittest.mock import patch - -from behave import given -from behave import then -from behave import when -import keyring - -import toml -import yaml -from yaml.loader import SafeLoader - - -import jrnl.time -from jrnl import Journal -from jrnl import __version__ -from jrnl import plugins -from jrnl.cli import cli -from jrnl.config import load_config -from jrnl.os_compat import split_args -from jrnl.override import apply_overrides, _recursively_apply - -try: - import parsedatetime.parsedatetime_consts as pdt -except ImportError: - import parsedatetime as pdt - -consts = pdt.Constants(usePyICU=False) -consts.DOWParseStyle = -1 # Prefers past weekdays -CALENDAR = pdt.Calendar(consts) - - -class TestKeyring(keyring.backend.KeyringBackend): - """A test keyring that just stores its values in a hash""" - - priority = 1 - keys = defaultdict(dict) - - def set_password(self, servicename, username, password): - self.keys[servicename][username] = password - - def get_password(self, servicename, username): - return self.keys[servicename].get(username) - - def delete_password(self, servicename, username): - self.keys[servicename][username] = None - - -class NoKeyring(keyring.backend.KeyringBackend): - """A keyring that simulated an environment with no keyring backend.""" - - priority = 2 - keys = defaultdict(dict) - - def set_password(self, servicename, username, password): - raise keyring.errors.NoKeyringError - - def get_password(self, servicename, username): - raise keyring.errors.NoKeyringError - - def delete_password(self, servicename, username): - raise keyring.errors.NoKeyringError - - -class FailedKeyring(keyring.backend.KeyringBackend): - """ - A keyring that cannot be retrieved. - """ - - priority = 2 - - def set_password(self, servicename, username, password): - raise keyring.errors.KeyringError - - def get_password(self, servicename, username): - raise keyring.errors.KeyringError - - def delete_password(self, servicename, username): - raise keyring.errors.KeyringError - - -# set a default keyring -keyring.set_keyring(TestKeyring()) - - -def read_journal(context, journal_name="default"): - configuration = load_config(context.config_path) - with open(configuration["journals"][journal_name]) as journal_file: - journal = journal_file.read() - return journal - - -def open_journal(context, journal_name="default"): - configuration = load_config(context.config_path) - journal_conf = configuration["journals"][journal_name] - - # We can override the default config on a by-journal basis - if type(journal_conf) is dict: - configuration.update(journal_conf) - # But also just give them a string to point to the journal file - else: - configuration["journal"] = journal_conf - - return Journal.open_journal(journal_name, configuration) - - -def read_value_from_string(string): - if string[0] == "{": - # Handle value being a dictionary - return ast.literal_eval(string) - - # Takes strings like "bool:true" or "int:32" and coerces them into proper type - string_parts = string.split(":") - if len(string_parts) > 1: - type = string_parts[0] - value = string_parts[1:][0] # rest of the text - value = {"bool": lambda v: v.lower() == "true", "int": int, "str": str}[type]( - value - ) - else: - value = string_parts[0] - return value - - -@given('we use the config "{config_file}"') -def set_config(context, config_file): - full_path = os.path.join("features/configs", config_file) - - context.config_path = os.path.abspath(full_path) - - if config_file.endswith("yaml") and os.path.exists(full_path): - # Add jrnl version to file for 2.x journals - with open(context.config_path, "a") as cf: - cf.write("version: {}".format(__version__)) - - -@given('we use the password "{password}" if prompted') -def use_password_forever(context, password): - context.password = password - - -@given('we use the password "{password}" {num:d} times if prompted') -def use_password(context, password, num=1): - context.password = iter([password] * num) - - -@given("we have a keyring") -@given("we have a {type} keyring") -def set_keyring(context, type=""): - if type == "failed": - keyring.set_keyring(FailedKeyring()) - else: - keyring.set_keyring(TestKeyring()) - - -@given("we do not have a keyring") -def disable_keyring(context): - keyring.core.set_keyring(NoKeyring()) - - -@given('we set current date and time to "{dt}"') -def set_datetime(context, dt): - context.now = dt - - -@when('we change directory to "{path}"') -def move_up_dir(context, path): - os.chdir(path) - - -@when("we open the editor and {method}") -@when('we open the editor and {method} "{text}"') -@when("we open the editor and {method} nothing") -@when("we open the editor and {method} nothing") -def open_editor_and_enter(context, method, text=""): - text = text or context.text or "" - - if method == "enter": - file_method = "w+" - elif method == "append": - file_method = "a" - else: - file_method = "r+" - - def _mock_editor(command): - context.editor_command = command - tmpfile = command[-1] - with open(tmpfile, file_method) as f: - f.write(text) - - return tmpfile - - if "password" in context: - password = context.password - else: - password = "" - - # fmt: off - # see: https://github.com/psf/black/issues/664 - with \ - patch("subprocess.call", side_effect=_mock_editor) as mock_editor, \ - patch("getpass.getpass", side_effect=_mock_getpass(password)) as mock_getpass, \ - patch("sys.stdin.isatty", return_value=True), \ - patch("jrnl.time.parse", side_effect=_mock_time_parse(context)), \ - patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ - patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ - : - context.editor = mock_editor - context.getpass = mock_getpass - try: - cli(["--edit"]) - context.exit_status = 0 - except SystemExit as e: - context.exit_status = e.code - - # fmt: on - - -@then("the editor should have been called") -@then("the editor should have been called with {num} arguments") -def count_editor_args(context, num=None): - assert context.editor.called - - if isinstance(num, int): - assert len(context.editor_command) == int(num) - - -@then("the editor should not have been called") -def no_editor_called(context, num=None): - assert "editor" not in context or not context.editor.called - - -@then('one editor argument should be "{arg}"') -def contains_editor_arg(context, arg): - args = context.editor_command - assert ( - arg in args and args.count(arg) == 1 - ), f"\narg not in args exactly 1 time:\n{arg}\n{str(args)}" - - -@then('one editor argument should match "{regex}"') -def matches_editor_arg(context, regex): - args = context.editor_command - matches = list(filter(lambda x: re.search(regex, x), args)) - assert ( - len(matches) == 1 - ), f"\nRegex didn't match exactly 1 time:\n{regex}\n{str(args)}" - - -@then("the editor file content should {method}") -@then("the editor file content should {method} empty") -@then('the editor file content should {method} "{text}"') -def contains_editor_file(context, method, text=""): - text = text or context.text or "" - content = context.editor_file.get("content") - format = f'\n"""\n{content}\n"""\n' - if method == "be": - assert content == text, format - elif method == "contain": - assert text in content, format - else: - assert False, f"Method '{method}' not supported" - - -@then('the temporary filename suffix should be "{suffix}"') -def extension_editor_file(context, suffix): - filename = Path(context.editor_file["name"]).name - delimiter = "-" if "-" in filename else "." - filename_suffix = delimiter + filename.split(delimiter)[-1] - assert filename_suffix == suffix - - -def _mock_getpass(inputs): - def prompt_return(prompt=""): - if type(inputs) == str: - return inputs - try: - return next(inputs) - except StopIteration: - raise KeyboardInterrupt - - return prompt_return - - -def _mock_input(inputs): - def prompt_return(prompt=""): - try: - val = next(inputs) - print(prompt, val) - return val - except StopIteration: - raise KeyboardInterrupt - - return prompt_return - - -def _mock_time_parse(context): - original_parse = jrnl.time.parse - if "now" not in context: - return original_parse - - def wrapper(input, *args, **kwargs): - input = context.now if input == "now" else input - return original_parse(input, *args, **kwargs) - - return wrapper - - -@when('we run "{command}" and enter') -@when('we run "{command}" and enter nothing') -@when('we run "{command}" and enter "{inputs}"') -def run_with_input(context, command, inputs=""): - # create an iterator through all inputs. These inputs will be fed one by one - # to the mocked calls for 'input()', 'util.getpass()' and 'sys.stdin.read()' - if context.text: - text = iter(context.text.split("\n")) - else: - text = iter([inputs]) - - args = split_args(command)[1:] - context.args = args - - def _mock_editor(command): - context.editor_command = command - tmpfile = command[-1] - with open(tmpfile, "r") as editor_file: - file_content = editor_file.read() - context.editor_file = {"name": tmpfile, "content": file_content} - Path(tmpfile).touch() - - if "password" in context: - password = context.password - else: - password = text - - # fmt: off - # see: https://github.com/psf/black/issues/664 - with \ - patch("builtins.input", side_effect=_mock_input(text)) as mock_input, \ - patch("getpass.getpass", side_effect=_mock_getpass(password)) as mock_getpass, \ - patch("sys.stdin.read", side_effect=text) as mock_read, \ - patch("subprocess.call", side_effect=_mock_editor) as mock_editor, \ - patch("jrnl.time.parse", side_effect=_mock_time_parse(context)), \ - patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ - patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ - : - try: - cli(args or []) - context.exit_status = 0 - except SystemExit as e: - context.exit_status = e.code - - # put mocks into context so they can be checked later in "then" statements - context.editor = mock_editor - context.input = mock_input - context.getpass = mock_getpass - context.read = mock_read - context.iter_text = text - - context.execute_steps(''' - Then all input was used - And at least one input method was called - ''') - - # fmt: on - - -@then("at least one input method was called") -def inputs_were_called(context): - assert ( - context.input.called - or context.getpass.called - or context.read.called - or context.editor.called - ) - - -@then("we should be prompted for a password") -def password_was_called(context): - assert context.getpass.called - - -@then("we should not be prompted for a password") -def password_was_not_called(context): - assert not context.getpass.called - - -@then("all input was used") -def all_input_was_used(context): - # all inputs were used (ignore if empty string) - for temp in context.iter_text: - assert "" == temp, "Not all inputs were consumed" - - -@when('we run "{command}"') -@when('we run "{command}" and pipe') -@when('we run "{command}" and pipe "{text}"') -def run(context, command, text=""): - text = text or context.text or "" - - if "config_path" in context and context.config_path is not None: - with open(context.config_path) as f: - context.jrnl_config = yaml.load(f, Loader=yaml.SafeLoader) - else: - context.jrnl_config = None - - if "cache_dir" in context and context.cache_dir is not None: - cache_dir = os.path.join("features", "cache", context.cache_dir) - command = command.format(cache_dir=cache_dir) - if "config_path" in context and context.config_path is not None: - with open(context.config_path, "r") as f: - cfg = yaml.load(f, Loader=SafeLoader) - context.jrnl_config = cfg - - args = split_args(command) - context.args = args[1:] - - def _mock_editor(command): - context.editor_command = command - tmpfile = command[-1] - with open(tmpfile, "r") as editor_file: - file_content = editor_file.read() - context.editor_file = {"name": tmpfile, "content": file_content} - Path(tmpfile).touch() - - if "password" in context: - password = context.password - else: - password = iter(text) - - try: - # fmt: off - # see: https://github.com/psf/black/issues/664 - with \ - patch("sys.argv", args), \ - patch("getpass.getpass", side_effect=_mock_getpass(password)) as mock_getpass, \ - patch("subprocess.call", side_effect=_mock_editor) as mock_editor, \ - patch("sys.stdin.read", side_effect=lambda: text), \ - patch("jrnl.time.parse", side_effect=_mock_time_parse(context)), \ - patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ - patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ - : - context.editor = mock_editor - context.getpass = mock_getpass - cli(args[1:]) - context.exit_status = 0 - # fmt: on - except SystemExit as e: - context.exit_status = e.code - - -@given('we load template "{filename}"') -def load_template(context, filename): - full_path = os.path.join("features/data/templates", filename) - exporter = plugins.template_exporter.__exporter_from_file(full_path) - plugins.__exporter_types[exporter.names[0]] = exporter - - -@when('we set the keyring password of "{journal}" to "{password}"') -def set_keyring_password(context, journal, password): - keyring.set_password("jrnl", journal, password) - - -@then("we should get an error") -def has_error(context): - assert context.exit_status != 0, context.exit_status - - -@then("we should get no error") -def no_error(context): - assert context.exit_status == 0, context.exit_status - - -@then("we flush the output") -def flush_stdout(context): - context.stdout_capture.truncate(0) - context.stdout_capture.seek(0) - - -@then("we flush the error output") -def flush_stderr(context): - context.stderr_capture.truncate(0) - context.stderr_capture.seek(0) - - -@then("we flush all the output") -def flush_all_output(context): - context.execute_steps( - """ - Then we flush the output - Then we flush the error output - """ - ) - - -@then("the output should be") -@then("the output should be empty") -@then('the output should be "{text}"') -def check_output(context, text=None): - text = (text or context.text or "").strip().splitlines() - out = context.stdout_capture.getvalue().strip().splitlines() - assert len(text) == len(out), "Output has {} lines (expected: {})".format( - len(out), len(text) - ) - for line_text, line_out in zip(text, out): - assert line_text.strip() == line_out.strip(), [ - line_text.strip(), - line_out.strip(), - ] - - -@then('the output should contain "{text}" in the local time') -def check_output_time_inline(context, text): - out = context.stdout_capture.getvalue() - date, flag = CALENDAR.parse(text) - output_date = time.strftime("%Y-%m-%d %H:%M", date) - assert output_date in out, output_date - - -@then("the output should contain pyproject.toml version") -def check_output_version_inline(context): - out = context.stdout_capture.getvalue() - pyproject = (Path(__file__) / ".." / ".." / ".." / "pyproject.toml").resolve() - pyproject_contents = toml.load(pyproject) - pyproject_version = pyproject_contents["tool"]["poetry"]["version"] - assert pyproject_version in out, pyproject_version - - -@then("the output should contain") -@then('the output should contain "{text}"') -@then('the output should contain "{text}" or "{text2}"') -def check_output_inline(context, text=None, text2=None): - text = text or context.text - out = context.stdout_capture.getvalue() - assert (text and text in out) or (text2 and text2 in out) - - -@then("the error output should contain") -@then('the error output should contain "{text}"') -@then('the error output should contain "{text}" or "{text2}"') -def check_error_output_inline(context, text=None, text2=None): - text = text or context.text - out = context.stderr_capture.getvalue() - assert (text and text in out) or (text2 and text2 in out) - - -@then('the output should match "{regex}"') -@then('the output should match "{regex}" {num} times') -def matches_std_output(context, regex, num=1): - out = context.stdout_capture.getvalue() - matches = re.findall(regex, out) - assert ( - matches and len(matches) == num - ), f"\nRegex didn't match exactly {num} time(s):\n{regex}\n{str(out)}\n{str(matches)}" - - -@then('the error output should match "{regex}"') -@then('the error output should match "{regex}" {num} times') -def matches_err_ouput(context, regex, num=1): - out = context.stderr_capture.getvalue() - matches = re.findall(regex, out) - assert ( - matches and len(matches) == num - ), f"\nRegex didn't match exactly {num} time(s):\n{regex}\n{str(out)}\n{str(matches)}" - - -@then('the output should not contain "{text}"') -def check_output_not_inline(context, text): - out = context.stdout_capture.getvalue() - assert text not in out - - -@then('we should see the message "{text}"') -@then('the error output should be "{text}"') -def check_message(context, text): - out = context.stderr_capture.getvalue() - assert text in out, [text, out] - - -@then('we should not see the message "{text}"') -def check_not_message(context, text): - out = context.stderr_capture.getvalue() - assert text not in out, [text, out] - - -@then('the journal should contain "{text}"') -@then('journal "{journal_name}" should contain "{text}"') -def check_journal_content(context, text, journal_name="default"): - journal = read_journal(context, journal_name) - assert text in journal, journal - - -@then('the journal should not contain "{text}"') -@then('journal "{journal_name}" should not contain "{text}"') -def check_not_journal_content(context, text, journal_name="default"): - journal = read_journal(context, journal_name) - assert text not in journal, journal - - -@then("the journal should not exist") -@then('journal "{journal_name}" should not exist') -def journal_doesnt_exist(context, journal_name="default"): - configuration = load_config(context.config_path) - - journal_path = configuration["journals"][journal_name] - assert not os.path.exists(journal_path) - - -@then("the journal should exist") -@then('journal "{journal_name}" should exist') -def journal_exists(context, journal_name="default"): - configuration = load_config(context.config_path) - - journal_path = configuration["journals"][journal_name] - assert os.path.exists(journal_path) - - -@then('the config should have "{key}" set to') -@then('the config should have "{key}" set to "{value}"') -@then('the config for journal "{journal}" should have "{key}" set to "{value}"') -def config_var(context, key, value="", journal=None): - key_as_vec = key.split(".") - - if "args" in context: - parsed = parse_args(context.args) - overrides = parsed.config_override - value = read_value_from_string(value or context.text or "") - configuration = load_config(context.config_path) - - if journal: - configuration = configuration["journals"][journal] - - if overrides: - with patch.object( - jrnl.override, "_recursively_apply", wraps=_recursively_apply - ) as spy_recurse: - configuration = apply_overrides(overrides, configuration) - runtime_cfg = spy_recurse.call_args_list[0][0][0] - else: - runtime_cfg = configuration - # extract the value of the desired key from the configuration after overrides have been applied - for k in key_as_vec: - runtime_cfg = runtime_cfg["%s" % k] - assert runtime_cfg == value - - -@then('the config for journal "{journal}" should not have "{key}" set') -def config_no_var(context, key, value="", journal=None): - configuration = load_config(context.config_path) - - if journal: - configuration = configuration["journals"][journal] - - assert key not in configuration - - -@then("the journal should have {number:d} entries") -@then("the journal should have {number:d} entry") -@then('journal "{journal_name}" should have {number:d} entries') -@then('journal "{journal_name}" should have {number:d} entry') -def check_journal_entries(context, number, journal_name="default"): - journal = open_journal(context, journal_name) - assert len(journal.entries) == number - - -@when("the journal directory is listed") -def list_journal_directory(context, journal="default"): - with open(context.config_path) as config_file: - configuration = yaml.load(config_file, Loader=yaml.SafeLoader) - journal_path = configuration["journals"][journal] - for root, dirnames, f in os.walk(journal_path): - for file in f: - print(os.path.join(root, file)) - - -@then("fail") -def debug_fail(context): - assert False diff --git a/features/steps/export_steps.py b/features/steps/export_steps.py deleted file mode 100644 index 8141dc36..00000000 --- a/features/steps/export_steps.py +++ /dev/null @@ -1,200 +0,0 @@ -# Copyright (C) 2012-2021 jrnl contributors -# License: https://www.gnu.org/licenses/gpl-3.0.html - - -import json -import os -import shutil -import random -import string -from xml.etree import ElementTree -from behave import given -from behave import then - - -@then("the output should be {width:d} columns wide") -def check_output_width(context, width): - out = context.stdout_capture.getvalue() - out_lines = out.splitlines() - for line in out_lines: - assert len(line) <= width - - -@then("the output should be parsable as json") -def check_output_json(context): - out = context.stdout_capture.getvalue() - assert json.loads(out), out - - -@then('"{field}" in the json output should have {number:d} elements') -@then('"{field}" in the json output should have 1 element') -def check_output_field(context, field, number=1): - out = context.stdout_capture.getvalue() - out_json = json.loads(out) - assert field in out_json, [field, out_json] - assert len(out_json[field]) == number, len(out_json[field]) - - -@then('"{field}" in the json output should not contain "{key}"') -def check_output_field_not_key(context, field, key): - out = context.stdout_capture.getvalue() - out_json = json.loads(out) - assert field in out_json - assert key not in out_json[field] - - -@then('"{field}" in the json output should contain "{key}"') -def check_output_field_key(context, field, key): - out = context.stdout_capture.getvalue() - struct = json.loads(out) - - for node in field.split("."): - try: - struct = struct[int(node)] - except ValueError: - assert node in struct - struct = struct[node] - - assert key in struct - - -@then("the json output should contain {path}") -@then('the json output should contain {path} = "{value}"') -def check_json_output_path(context, path, value=None): - """E.g. - the json output should contain entries.0.title = "hello" - """ - out = context.stdout_capture.getvalue() - struct = json.loads(out) - - for node in path.split("."): - try: - struct = struct[int(node)] - except ValueError: - struct = struct[node] - - if value is not None: - assert struct == value, struct - else: - assert struct is not None - - -@then( - 'entry {entry_number:d} should have an array "{name}" with {items_number:d} elements' -) -def entry_array_count(context, entry_number, name, items_number): - # note that entry_number is 1-indexed. - out = context.stdout_capture.getvalue() - out_json = json.loads(out) - assert len(out_json["entries"][entry_number - 1][name]) == items_number - - -@then("the output should be a valid XML string") -def assert_valid_xml_string(context): - output = context.stdout_capture.getvalue() - xml_tree = ElementTree.fromstring(output) - assert xml_tree, output - - -@then('"{item}" node in the xml output should have {number:d} elements') -def assert_xml_output_entries_count(context, item, number): - output = context.stdout_capture.getvalue() - xml_tree = ElementTree.fromstring(output) - - xml_tags = (node.tag for node in xml_tree) - assert item in xml_tags, str(list(xml_tags)) - - actual_entry_count = len(xml_tree.find(item)) - assert actual_entry_count == number, actual_entry_count - - -@then('there should be {number:d} "{item}" elements') -def count_elements(context, number, item): - output = context.stdout_capture.getvalue() - xml_tree = ElementTree.fromstring(output) - assert len(xml_tree.findall(".//" + item)) == number - - -@then('"tags" in the xml output should contain {expected_tags_json_list}') -def assert_xml_output_tags(context, expected_tags_json_list): - output = context.stdout_capture.getvalue() - xml_tree = ElementTree.fromstring(output) - - xml_tags = (node.tag for node in xml_tree) - assert "tags" in xml_tags, str(list(xml_tags)) - - expected_tags = json.loads(expected_tags_json_list) - actual_tags = set(t.attrib["name"] for t in xml_tree.find("tags")) - assert actual_tags == set(expected_tags), [actual_tags, set(expected_tags)] - - -@given('we create cache directory "{dir_name}"') -@given("we create a cache directory") -def create_directory(context, dir_name=None): - if not dir_name: - dir_name = "cache_" + "".join( - random.choices(string.ascii_uppercase + string.digits, k=20) - ) - - working_dir = os.path.join("features", "cache", dir_name) - if os.path.exists(working_dir): - shutil.rmtree(working_dir) - os.makedirs(working_dir) - context.cache_dir = dir_name - - -@then('cache "{dir_name}" should contain the files') -@then('cache "{dir_name}" should contain the files {expected_files_json_list}') -@then("the cache should contain the files") -def assert_dir_contains_files(context, dir_name=None, expected_files_json_list=""): - if not dir_name: - dir_name = context.cache_dir - - working_dir = os.path.join("features", "cache", dir_name) - actual_files = os.listdir(working_dir) - - expected_files = context.text or expected_files_json_list - expected_files = expected_files.split("\n") - - # sort to deal with inconsistent default file ordering on different OS's - actual_files.sort() - expected_files.sort() - - assert actual_files == expected_files, [actual_files, expected_files] - - -@then('the content of file "{file_path}" in cache directory "{cache_dir}" should be') -@then('the content of file "{file_path}" in the cache should be') -def assert_exported_yaml_file_content(context, file_path, cache_dir=None): - if not cache_dir: - cache_dir = context.cache_dir - - expected_content = context.text.strip().splitlines() - full_file_path = os.path.join("features", "cache", cache_dir, file_path) - - with open(full_file_path, "r") as f: - actual_content = f.read().strip().splitlines() - - for actual_line, expected_line in zip(actual_content, expected_content): - if actual_line.startswith("tags: ") and expected_line.startswith("tags: "): - assert_equal_tags_ignoring_order( - actual_line, expected_line, actual_content, expected_content - ) - else: - assert actual_line.strip() == expected_line.strip(), [ - [actual_line.strip(), expected_line.strip()], - [actual_content, expected_content], - ] - - -def assert_equal_tags_ignoring_order( - actual_line, expected_line, actual_content, expected_content -): - actual_tags = set(tag.strip() for tag in actual_line[len("tags: ") :].split(",")) - expected_tags = set( - tag.strip() for tag in expected_line[len("tags: ") :].split(",") - ) - assert actual_tags == expected_tags, [ - [actual_tags, expected_tags], - [expected_content, actual_content], - ] diff --git a/features/steps/override.py b/features/steps/override.py deleted file mode 100644 index ff1760ed..00000000 --- a/features/steps/override.py +++ /dev/null @@ -1,77 +0,0 @@ -from jrnl.jrnl import run -from unittest import mock - -# from __future__ import with_statement -from jrnl.args import parse_args -from behave import then - -from features.steps.core import _mock_getpass, _mock_time_parse - - -@then("the editor {editor} should have been called") -@then("No editor should have been called") -def editor_override(context, editor=None): - def _mock_write_in_editor(config): - editor = config["editor"] - journal = "features/journals/journal.jrnl" - context.tmpfile = journal - print("%s has been launched" % editor) - return journal - - if "password" in context: - password = context.password - else: - password = "" - # fmt: off - # see: https://github.com/psf/black/issues/664 - with \ - mock.patch("jrnl.jrnl._write_in_editor", side_effect=_mock_write_in_editor(context.jrnl_config)) as mock_write_in_editor, \ - mock.patch("sys.stdin.isatty", return_value=True), \ - mock.patch('getpass.getpass',side_effect=_mock_getpass(password)), \ - mock.patch("jrnl.time.parse", side_effect = _mock_time_parse(context)), \ - mock.patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ - mock.patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ - : - try : - parsed_args = parse_args(context.args) - run(parsed_args) - context.exit_status = 0 - context.editor = mock_write_in_editor - expected_config = context.jrnl_config - expected_config['editor'] = '%s'%editor - expected_config['journal'] ='features/journals/journal.jrnl' - - if editor is not None: - assert mock_write_in_editor.call_count == 1 - assert mock_write_in_editor.call_args[0][0]['editor']==editor - else: - # Expect that editor is *never* called - mock_write_in_editor.assert_not_called() - except SystemExit as e: - context.exit_status = e.code - # fmt: on - - -@then("the stdin prompt should have been called") -def override_editor_to_use_stdin(context): - - try: - with mock.patch( - "sys.stdin.read", - return_value="Zwei peanuts walk into a bar und one of zem was a-salted", - ) as mock_stdin_read, mock.patch( - "jrnl.install.load_or_install_jrnl", return_value=context.jrnl_config - ), mock.patch( - "jrnl.Journal.open_journal", - spec=False, - return_value="features/journals/journal.jrnl", - ), mock.patch( - "getpass.getpass", side_effect=_mock_getpass("test") - ): - parsed_args = parse_args(context.args) - run(parsed_args) - context.exit_status = 0 - mock_stdin_read.assert_called_once() - - except SystemExit as e: - context.exit_status = e.code diff --git a/features/tag.feature b/features/tag.feature deleted file mode 100644 index b7b687b5..00000000 --- a/features/tag.feature +++ /dev/null @@ -1,53 +0,0 @@ -Feature: Tagging -# See search.feature for tag-related searches -# And format.feature for tag-related output - - Scenario Outline: Tags should allow certain special characters such as /, +, # - Given we use the config ".yaml" - When we run "jrnl 2020-09-26: This is an entry about @os/2 and @c++ and @c#" - When we run "jrnl --tags -on 2020-09-26" - Then we should get no error - And the output should be - """ - @os/2 : 1 - @c++ : 1 - @c# : 1 - """ - - Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | - - Scenario Outline: Emails addresses should not be parsed as tags - Given we use the config ".yaml" - When we run "jrnl 2020-09-26: The email address test@example.com does not seem to work for me" - When we run "jrnl 2020-09-26: The email address test@example.org also does not work for me" - When we run "jrnl 2020-09-26: I tried test@example.org and test@example.edu too" - Then we flush the output - When we run "jrnl --tags -on 2020-09-26" - Then we should get no error - And the output should be "[No tags found in journal.]" - - Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | - - Scenario Outline: Entry can start and end with tags - Given we use the config ".yaml" - When we run "jrnl 2020-09-26: @foo came over, we went to a @bar" - When we run "jrnl --tags -on 2020-09-26" - Then the output should be - """ - @foo : 1 - @bar : 1 - """ - - Examples: configs - | config | - | basic_onefile | - | basic_folder | - | basic_dayone | diff --git a/features/upgrade.feature b/features/upgrade.feature deleted file mode 100644 index fda47363..00000000 --- a/features/upgrade.feature +++ /dev/null @@ -1,71 +0,0 @@ -Feature: Upgrading Journals from 1.x.x to 2.x.x - - Scenario: Upgrade and parse journals with square brackets - Given we use the config "upgrade_from_195.json" - When we run "jrnl -9" and enter "Y" - Then the journal should have 2 entries - And the output should contain - """ - 2010-06-10 15:00 A life without chocolate is like a bad analogy. - """ - And the output should contain - """ - 2013-06-10 15:40 He said "[this] is the best time to be alive". - """ - - Scenario: Upgrading a journal encrypted with jrnl 1.x - Given we use the config "encrypted_old.json" - When we run "jrnl -n 1" and enter - """ - Y - bad doggie no biscuit - bad doggie no biscuit - """ - Then we should be prompted for a password - And the output should contain "2013-06-10 15:40 Life is good" - - Scenario: Upgrading a config without colors to colors - Given we use the config "no_colors.yaml" - When we run "jrnl -n 1" - Then the config should have "colors" set to - """ - { - 'date':'none', - 'title':'none', - 'body':'none', - 'tags':'none' - } - """ - - Scenario: Upgrade and parse journals with little endian date format - Given we use the config "upgrade_from_195_little_endian_dates.json" - When we run "jrnl -9" and enter "Y" - Then the journal should have 2 entries - And the output should contain - """ - 10.06.2010 15:00 A life without chocolate is like a bad analogy. - """ - And the output should contain - """ - 10.06.2013 15:40 He said "[this] is the best time to be alive". - """ - - Scenario: Upgrade with missing journal - Given we use the config "upgrade_from_195_with_missing_journal.json" - When we run "jrnl -ls" and enter - """" - Y - """ - Then the output should contain "Error: features/journals/missing.journal does not exist." - And we should get no error - - Scenario: Upgrade with missing encrypted journal - Given we use the config "upgrade_from_195_with_missing_encrypted_journal.json" - When we run "jrnl -ls" and enter - """ - Y - bad doggie no biscuit - """ - Then the output should contain "Error: features/journals/missing.journal does not exist." - And the error output should contain "We're all done" - And we should get no error diff --git a/features/write.feature b/features/write.feature deleted file mode 100644 index eb22e480..00000000 --- a/features/write.feature +++ /dev/null @@ -1,216 +0,0 @@ -Feature: Writing new entries. - - Scenario Outline: Multiline entry with punctuation should keep title punctuation - Given we use the config ".yaml" - And we use the password "bad doggie no biscuit" if prompted - When we run "jrnl This is. the title\\n This is the second line" - And we run "jrnl -n 1" - Then the output should contain "This is. the title" - - Examples: configs - | config_file | - | simple | - | empty_folder | - | dayone | - | encrypted | - - Scenario Outline: Single line entry with period should be split at period - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl This is. the title" - And we run "jrnl -1" - Then the output should contain "| the title" - - Examples: configs - | config_file | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario Outline: CJK entry should be split at fullwidth period without following space. - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl 七転び。八起き" - And we run "jrnl -1" - Then the output should contain "| 八起き" - - Examples: configs - | config_file | - | basic_onefile | - | basic_encrypted | - | basic_folder | - | basic_dayone | - - Scenario Outline: Writing an entry from command line should store the entry - Given we use the config ".yaml" - And we use the password "bad doggie no biscuit" if prompted - When we run "jrnl 23 july 2013: A cold and stormy day. I ate crisps on the sofa." - Then we should see the message "Entry added" - When we run "jrnl -n 1" - Then the output should contain "2013-07-23 09:00 A cold and stormy day." - - Examples: configs - | config_file | - | simple | - | empty_folder | - | dayone | - | encrypted | - - Scenario Outline: Writing a partial entry from command line with edit flag should go to the editor - Given we use the config ".yaml" - And we use the password "test" if prompted - When we run "jrnl this is a partial --edit" - Then we should see the message "Entry added" - Then the editor should have been called - And the editor file content should be - """ - this is a partial - """ - When we run "jrnl -n 1" - Then the output should contain "this is a partial" - - Examples: configs - | config_file | - | basic_onefile | - | basic_encrypted | - | basic_dayone | - | basic_folder | - - Scenario Outline: Writing an empty entry from the editor should yield "Nothing saved to file" message - Given we use the config ".yaml" - And we use the password "test" if prompted - When we open the editor and enter nothing - Then the error output should contain "[Nothing saved to file]" - - Examples: configs - | config_file | - | editor | - | editor_empty_folder | - | dayone | - | basic_encrypted | - | basic_onefile | - - @skip - Scenario Outline: Writing an empty entry from the command line with no editor should yield nothing - Given we use the config ".yaml" - And we use the password "bad doggie no biscuit" if prompted - When we run "jrnl" and enter nothing - Then the output should be empty - And the error output should contain "Writing Entry; on a blank line" - And the editor should not have been called - - Examples: configs - | config_file | - | simple | - | empty_folder | - | encrypted | - # | dayone | @todo - - Scenario Outline: Writing an entry does not print the entire journal - # https://github.com/jrnl-org/jrnl/issues/87 - Given we use the config ".yaml" - And we use the password "bad doggie no biscuit" if prompted - When we run "jrnl 23 july 2013: A cold and stormy day. I ate crisps on the sofa." - Then we should see the message "Entry added" - When we run "jrnl -n 1" - Then the output should not contain "Life is good" - - Examples: configs - | config_file | - | editor | - | editor_empty_folder | - | dayone | - | encrypted | - - Scenario Outline: Embedded period stays in title - Given we use the config ".yaml" - And we use the password "bad doggie no biscuit" if prompted - When we run "jrnl 04-24-2014: Created a new website - empty.com. Hope to get a lot of traffic." - Then we should see the message "Entry added" - When we run "jrnl -1" - Then the output should be - """ - 2014-04-24 09:00 Created a new website - empty.com. - | Hope to get a lot of traffic. - """ - - Examples: configs - | config_file | - | simple | - | empty_folder | - | dayone | - | encrypted | - - Scenario Outline: Write and read emoji support - Given we use the config ".yaml" - And we use the password "bad doggie no biscuit" if prompted - When we run "jrnl 23 july 2013: 🌞 sunny day. Saw an 🐘" - Then we should see the message "Entry added" - When we run "jrnl -n 1" - Then the output should contain "🌞" - And the output should contain "🐘" - - Examples: configs - | config_file | - | simple | - | empty_folder | - | dayone | - | encrypted | - - Scenario Outline: Writing an entry at the prompt (no editor) should store the entry - Given we use the config ".yaml" - And we use the password "bad doggie no biscuit" if prompted - When we run "jrnl" and enter "25 jul 2013: I saw Elvis. He's alive." - Then we should get no error - When we run "jrnl -on '2013-07-25'" - Then the output should contain "2013-07-25 09:00 I saw Elvis." - And the output should contain "| He's alive." - - Examples: configs - | config_file | - | simple | - | empty_folder | - | encrypted | - - @todo - Scenario: Writing an entry at the prompt (no editor) in DayOne journal - # Need to test DayOne w/out an editor - - Scenario: Writing into Dayone - Given we use the config "dayone.yaml" - When we run "jrnl 01 may 1979: Being born hurts." - And we run "jrnl -until 1980" - Then the output should be "1979-05-01 09:00 Being born hurts." - - Scenario: Writing into Dayone adds extended metadata - Given we use the config "dayone.yaml" - When we run "jrnl 01 may 1979: Being born hurts." - And we run "jrnl --export json" - Then "entries" in the json output should have 5 elements - And the json output should contain entries.0.creator.software_agent - And the json output should contain entries.0.creator.os_agent - And the json output should contain entries.0.creator.host_name - And the json output should contain entries.0.creator.generation_date - And the json output should contain entries.0.creator.device_agent - And "entries.0.creator.software_agent" in the json output should contain "jrnl" - - # fails when system time is UTC (as on Travis-CI) - @skip - Scenario: Title with an embedded period on DayOne journal - Given we use the config "dayone.yaml" - When we run "jrnl 04-24-2014: "Ran 6.2 miles today in 1:02:03. I'm feeling sore because I forgot to stretch."" - Then we should see the message "Entry added" - When we run "jrnl -1" - Then the output should be - """ - 2014-04-24 09:00 Ran 6.2 miles today in 1:02:03. - | I'm feeling sore because I forgot to stretch. - """ - - Scenario: Opening an folder that's not a DayOne folder should treat as folder journal - Given we use the config "empty_folder.yaml" - When we run "jrnl 23 july 2013: Testing folder journal." - Then we should see the message "Entry added" - When we run "jrnl -1" - Then the output should be "2013-07-23 09:00 Testing folder journal." diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index 2d06115d..bc7e0b88 100644 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -40,9 +40,7 @@ def run(args): original_config = config.copy() # Apply config overrides - overrides = args.config_override - if overrides: - config = apply_overrides(overrides, config) + config = apply_overrides(args, config) args = get_journal_name(args, config) config = scope_config(config, args.journal_name) diff --git a/jrnl/override.py b/jrnl/override.py index 7fd718f0..760b003e 100644 --- a/jrnl/override.py +++ b/jrnl/override.py @@ -1,7 +1,8 @@ from .config import update_config, make_yaml_valid_dict +from argparse import Namespace # import logging -def apply_overrides(overrides: list, base_config: dict) -> dict: +def apply_overrides(args: Namespace, base_config: dict) -> dict: """Unpack CLI provided overrides into the configuration tree. :param overrides: List of configuration key-value pairs collected from the CLI @@ -11,6 +12,10 @@ def apply_overrides(overrides: list, base_config: dict) -> dict: :return: Configuration to be used during runtime with the overrides applied :rtype: dict """ + overrides = vars(args).get("config_override", None) + if not overrides: + return base_config + cfg_with_overrides = base_config.copy() for pairs in overrides: diff --git a/poetry.lock b/poetry.lock index e718ea5a..8c86d892 100644 --- a/poetry.lock +++ b/poetry.lock @@ -69,23 +69,6 @@ category = "dev" optional = false python-versions = "*" -[[package]] -name = "behave" -version = "1.2.6" -description = "behave is behaviour-driven development, Python style" -category = "main" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" - -[package.dependencies] -parse = ">=1.8.2" -parse-type = ">=0.4.2" -six = ">=1.11" - -[package.extras] -develop = ["coverage", "pytest (>=3.0)", "pytest-cov", "tox", "invoke (>=0.21.0)", "path.py (>=8.1.2)", "pycmd", "pathlib", "modernize (>=0.5)", "pylint"] -docs = ["sphinx (>=1.6)", "sphinx-bootstrap-theme (>=0.6)"] - [[package]] name = "black" version = "21.9b0" @@ -177,7 +160,7 @@ test = ["pytest (>=6.2.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pr [[package]] name = "decorator" -version = "5.0.9" +version = "5.1.0" description = "Decorators for Humans" category = "dev" optional = false @@ -199,7 +182,7 @@ pyflakes = ">=2.3.0,<2.4.0" [[package]] name = "ghp-import" -version = "2.0.1" +version = "2.0.2" description = "Copy your docs directly to the gh-pages branch." category = "dev" optional = false @@ -221,7 +204,7 @@ python-versions = "*" [[package]] name = "importlib-metadata" -version = "4.6.1" +version = "4.8.1" description = "Read metadata from Python packages" category = "main" optional = false @@ -259,7 +242,7 @@ toml = {version = ">=0.10.2", markers = "python_version > \"3.6\""} [[package]] name = "ipython" -version = "7.25.0" +version = "7.28.0" description = "IPython: Productive Interactive Computing" category = "dev" optional = false @@ -289,14 +272,6 @@ parallel = ["ipyparallel"] qtconsole = ["qtconsole"] test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.17)"] -[[package]] -name = "ipython-genutils" -version = "0.2.0" -description = "Vestigial utilities from IPython" -category = "dev" -optional = false -python-versions = "*" - [[package]] name = "jedi" version = "0.18.0" @@ -314,14 +289,14 @@ testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<6.0.0)"] [[package]] name = "jeepney" -version = "0.7.0" +version = "0.7.1" description = "Low-level, pure Python DBus protocol wrapper." category = "main" optional = false python-versions = ">=3.6" [package.extras] -test = ["pytest", "pytest-trio", "pytest-asyncio", "testpath", "trio"] +test = ["pytest", "pytest-trio", "pytest-asyncio", "testpath", "trio", "async-timeout"] trio = ["trio", "async-generator"] [[package]] @@ -358,7 +333,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes [[package]] name = "mako" -version = "1.1.4" +version = "1.1.5" description = "A super-fast templating language that borrows the best ideas from the existing templating languages." category = "main" optional = false @@ -395,7 +370,7 @@ python-versions = ">=3.6" [[package]] name = "matplotlib-inline" -version = "0.1.2" +version = "0.1.3" description = "Inline Matplotlib backend for Jupyter" category = "dev" optional = false @@ -535,7 +510,7 @@ python-versions = "*" [[package]] name = "platformdirs" -version = "2.2.0" +version = "2.4.0" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false @@ -547,17 +522,18 @@ test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock [[package]] name = "pluggy" -version = "0.13.1" +version = "1.0.0" description = "plugin and hook calling mechanisms for python" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.dependencies] importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} [package.extras] dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] [[package]] name = "pprintpp" @@ -569,11 +545,11 @@ python-versions = "*" [[package]] name = "prompt-toolkit" -version = "3.0.19" +version = "3.0.20" description = "Library for building powerful interactive command lines in Python" category = "dev" optional = false -python-versions = ">=3.6.1" +python-versions = ">=3.6.2" [package.dependencies] wcwidth = "*" @@ -620,7 +596,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pygments" -version = "2.9.0" +version = "2.10.0" description = "Pygments is a syntax highlighting package written in Python." category = "dev" optional = false @@ -753,7 +729,7 @@ pyyaml = "*" [[package]] name = "regex" -version = "2021.7.6" +version = "2021.9.30" description = "Alternative regular expression module, to replace re." category = "dev" optional = false @@ -761,7 +737,7 @@ python-versions = "*" [[package]] name = "rich" -version = "10.6.0" +version = "10.11.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" category = "dev" optional = false @@ -814,7 +790,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "tomli" -version = "1.0.4" +version = "1.2.1" description = "A lil' TOML parser" category = "dev" optional = false @@ -822,15 +798,12 @@ python-versions = ">=3.6" [[package]] name = "traitlets" -version = "5.0.5" +version = "5.1.0" description = "Traitlets Python configuration system" category = "dev" optional = false python-versions = ">=3.7" -[package.dependencies] -ipython-genutils = "*" - [package.extras] test = ["pytest"] @@ -863,14 +836,14 @@ pytz = "*" [[package]] name = "watchdog" -version = "2.1.3" +version = "2.1.6" description = "Filesystem events monitoring" category = "dev" optional = false python-versions = ">=3.6" [package.extras] -watchmedo = ["PyYAML (>=3.10)", "argh (>=0.24.1)"] +watchmedo = ["PyYAML (>=3.10)"] [[package]] name = "wcwidth" @@ -907,7 +880,7 @@ test = ["coverage", "flake8", "wheel"] [[package]] name = "zipp" -version = "3.5.0" +version = "3.6.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false @@ -918,12 +891,12 @@ docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] [extras] -testing = ["behave", "pytest", "pytest-bdd", "toml"] +testing = ["pytest", "pytest-bdd", "toml"] [metadata] lock-version = "1.1" python-versions = ">=3.7.0, <3.11" -content-hash = "c4f943f3dbd96f5aab8ad0ef2f3d3f6a7096dc75ea7d3e449949695d340208fb" +content-hash = "fc24941ef7a065e56487518ccab053638f053e49f4e47f1746cd9fbfcef40546" [metadata.files] ansiwrap = [ @@ -953,10 +926,6 @@ backcall = [ {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] -behave = [ - {file = "behave-1.2.6-py2.py3-none-any.whl", hash = "sha256:ebda1a6c9e5bfe95c5f9f0a2794e01c7098b3dde86c10a95d8621c5907ff6f1c"}, - {file = "behave-1.2.6.tar.gz", hash = "sha256:b9662327aa53294c1351b0a9c369093ccec1d21026f050c3bd9b3e5cccf81a86"}, -] black = [ {file = "black-21.9b0-py3-none-any.whl", hash = "sha256:380f1b5da05e5a1429225676655dddb96f5ae8c75bdf91e53d798871b902a115"}, {file = "black-21.9b0.tar.gz", hash = "sha256:7de4cfc7eb6b710de325712d40125689101d21d25283eed7e9998722cf10eb91"}, @@ -969,11 +938,6 @@ cffi = [ {file = "cffi-1.14.6-cp27-cp27m-win_amd64.whl", hash = "sha256:7bcac9a2b4fdbed2c16fa5681356d7121ecabf041f18d97ed5b8e0dd38a80224"}, {file = "cffi-1.14.6-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ed38b924ce794e505647f7c331b22a693bee1538fdf46b0222c4717b42f744e7"}, {file = "cffi-1.14.6-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e22dcb48709fc51a7b58a927391b23ab37eb3737a98ac4338e2448bef8559b33"}, - {file = "cffi-1.14.6-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:aedb15f0a5a5949ecb129a82b72b19df97bbbca024081ed2ef88bd5c0a610534"}, - {file = "cffi-1.14.6-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:48916e459c54c4a70e52745639f1db524542140433599e13911b2f329834276a"}, - {file = "cffi-1.14.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f627688813d0a4140153ff532537fbe4afea5a3dffce1f9deb7f91f848a832b5"}, - {file = "cffi-1.14.6-cp35-cp35m-win32.whl", hash = "sha256:f0010c6f9d1a4011e429109fda55a225921e3206e7f62a0c22a35344bfd13cca"}, - {file = "cffi-1.14.6-cp35-cp35m-win_amd64.whl", hash = "sha256:57e555a9feb4a8460415f1aac331a2dc833b1115284f7ded7278b54afc5bd218"}, {file = "cffi-1.14.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e8c6a99be100371dbb046880e7a282152aa5d6127ae01783e37662ef73850d8f"}, {file = "cffi-1.14.6-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:19ca0dbdeda3b2615421d54bef8985f72af6e0c47082a8d26122adac81a95872"}, {file = "cffi-1.14.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d950695ae4381ecd856bcaf2b1e866720e4ab9a1498cba61c602e56630ca7195"}, @@ -1043,23 +1007,23 @@ cryptography = [ {file = "cryptography-35.0.0.tar.gz", hash = "sha256:9933f28f70d0517686bd7de36166dda42094eac49415459d9bdf5e7df3e0086d"}, ] decorator = [ - {file = "decorator-5.0.9-py3-none-any.whl", hash = "sha256:6e5c199c16f7a9f0e3a61a4a54b3d27e7dad0dbdde92b944426cb20914376323"}, - {file = "decorator-5.0.9.tar.gz", hash = "sha256:72ecfba4320a893c53f9706bebb2d55c270c1e51a28789361aa93e4a21319ed5"}, + {file = "decorator-5.1.0-py3-none-any.whl", hash = "sha256:7b12e7c3c6ab203a29e157335e9122cb03de9ab7264b137594103fd4a683b374"}, + {file = "decorator-5.1.0.tar.gz", hash = "sha256:e59913af105b9860aa2c8d3272d9de5a56a4e608db9a2f167a8480b323d529a7"}, ] flake8 = [ {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, ] ghp-import = [ - {file = "ghp-import-2.0.1.tar.gz", hash = "sha256:753de2eace6e0f7d4edfb3cce5e3c3b98cd52aadb80163303d1d036bda7b4483"}, - {file = "ghp_import-2.0.1-py3-none-any.whl", hash = "sha256:8241a8e9f8dd3c1fafe9696e6e081b57a208ef907e9939c44e7415e407ab40ea"}, + {file = "ghp-import-2.0.2.tar.gz", hash = "sha256:947b3771f11be850c852c64b561c600fdddf794bab363060854c1ee7ad05e071"}, + {file = "ghp_import-2.0.2-py3-none-any.whl", hash = "sha256:5f8962b30b20652cdffa9c5a9812f7de6bcb56ec475acac579807719bf242c46"}, ] glob2 = [ {file = "glob2-0.7.tar.gz", hash = "sha256:85c3dbd07c8aa26d63d7aacee34fa86e9a91a3873bc30bf62ec46e531f92ab8c"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.6.1-py3-none-any.whl", hash = "sha256:9f55f560e116f8643ecf2922d9cd3e1c7e8d52e683178fecd9d08f6aa357e11e"}, - {file = "importlib_metadata-4.6.1.tar.gz", hash = "sha256:079ada16b7fc30dfbb5d13399a5113110dab1aa7c2bc62f66af75f0b717c8cac"}, + {file = "importlib_metadata-4.8.1-py3-none-any.whl", hash = "sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15"}, + {file = "importlib_metadata-4.8.1.tar.gz", hash = "sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -1069,20 +1033,16 @@ ipdb = [ {file = "ipdb-0.13.9.tar.gz", hash = "sha256:951bd9a64731c444fd907a5ce268543020086a697f6be08f7cc2c9a752a278c5"}, ] ipython = [ - {file = "ipython-7.25.0-py3-none-any.whl", hash = "sha256:aa21412f2b04ad1a652e30564fff6b4de04726ce875eab222c8430edc6db383a"}, - {file = "ipython-7.25.0.tar.gz", hash = "sha256:54bbd1fe3882457aaf28ae060a5ccdef97f212a741754e420028d4ec5c2291dc"}, -] -ipython-genutils = [ - {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, - {file = "ipython_genutils-0.2.0.tar.gz", hash = "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"}, + {file = "ipython-7.28.0-py3-none-any.whl", hash = "sha256:f16148f9163e1e526f1008d7c8d966d9c15600ca20d1a754287cf96d00ba6f1d"}, + {file = "ipython-7.28.0.tar.gz", hash = "sha256:2097be5c814d1b974aea57673176a924c4c8c9583890e7a5f082f547b9975b11"}, ] jedi = [ {file = "jedi-0.18.0-py2.py3-none-any.whl", hash = "sha256:18456d83f65f400ab0c2d3319e48520420ef43b23a086fdc05dff34132f0fb93"}, {file = "jedi-0.18.0.tar.gz", hash = "sha256:92550a404bad8afed881a137ec9a461fed49eca661414be45059329614ed0707"}, ] jeepney = [ - {file = "jeepney-0.7.0-py3-none-any.whl", hash = "sha256:71335e7a4e93817982f473f3507bffc2eff7a544119ab9b73e089c8ba1409ba3"}, - {file = "jeepney-0.7.0.tar.gz", hash = "sha256:1237cd64c8f7ac3aa4b3f332c4d0fb4a8216f39eaa662ec904302d4d77de5a54"}, + {file = "jeepney-0.7.1-py3-none-any.whl", hash = "sha256:1b5a0ea5c0e7b166b2f5895b91a08c14de8915afda4407fb5022a195224958ac"}, + {file = "jeepney-0.7.1.tar.gz", hash = "sha256:fa9e232dfa0c498bd0b8a3a73b8d8a31978304dcef0515adc859d4e096f96f4f"}, ] jinja2 = [ {file = "Jinja2-3.0.1-py3-none-any.whl", hash = "sha256:1f06f2da51e7b56b8f238affdd6b4e2c61e39598a378cc49345bc1bd42a978a4"}, @@ -1093,30 +1053,20 @@ keyring = [ {file = "keyring-23.2.1.tar.gz", hash = "sha256:6334aee6073db2fb1f30892697b1730105b5e9a77ce7e61fca6b435225493efe"}, ] mako = [ - {file = "Mako-1.1.4-py2.py3-none-any.whl", hash = "sha256:aea166356da44b9b830c8023cd9b557fa856bd8b4035d6de771ca027dfc5cc6e"}, - {file = "Mako-1.1.4.tar.gz", hash = "sha256:17831f0b7087c313c0ffae2bcbbd3c1d5ba9eeac9c38f2eb7b50e8c99fe9d5ab"}, + {file = "Mako-1.1.5-py2.py3-none-any.whl", hash = "sha256:6804ee66a7f6a6416910463b00d76a7b25194cd27f1918500c5bd7be2a088a23"}, + {file = "Mako-1.1.5.tar.gz", hash = "sha256:169fa52af22a91900d852e937400e79f535496191c63712e3b9fda5a9bed6fc3"}, ] markdown = [ {file = "Markdown-3.3.4-py3-none-any.whl", hash = "sha256:96c3ba1261de2f7547b46a00ea8463832c921d3f9d6aba3f255a6f71386db20c"}, {file = "Markdown-3.3.4.tar.gz", hash = "sha256:31b5b491868dcc87d6c24b7e3d19a0d730d59d3e46f4eea6430a321bed387a49"}, ] markupsafe = [ - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, @@ -1125,21 +1075,14 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, @@ -1149,16 +1092,13 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, ] matplotlib-inline = [ - {file = "matplotlib-inline-0.1.2.tar.gz", hash = "sha256:f41d5ff73c9f5385775d5c0bc13b424535c8402fe70ea8210f93e11f3683993e"}, - {file = "matplotlib_inline-0.1.2-py3-none-any.whl", hash = "sha256:5cf1176f554abb4fa98cb362aa2b55c500147e4bdbb07e3fda359143e1da0811"}, + {file = "matplotlib-inline-0.1.3.tar.gz", hash = "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee"}, + {file = "matplotlib_inline-0.1.3-py3-none-any.whl", hash = "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"}, ] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, @@ -1208,20 +1148,20 @@ pickleshare = [ {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] platformdirs = [ - {file = "platformdirs-2.2.0-py3-none-any.whl", hash = "sha256:4666d822218db6a262bdfdc9c39d21f23b4cfdb08af331a81e92751daf6c866c"}, - {file = "platformdirs-2.2.0.tar.gz", hash = "sha256:632daad3ab546bd8e6af0537d09805cec458dce201bccfe23012df73332e181e"}, + {file = "platformdirs-2.4.0-py3-none-any.whl", hash = "sha256:8868bbe3c3c80d42f20156f22e7131d2fb321f5bc86a2a345375c6481a67021d"}, + {file = "platformdirs-2.4.0.tar.gz", hash = "sha256:367a5e80b3d04d2428ffa76d33f124cf11e8fff2acdaa9b43d545f5c7d661ef2"}, ] pluggy = [ - {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, - {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] pprintpp = [ {file = "pprintpp-0.4.0-py2.py3-none-any.whl", hash = "sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d"}, {file = "pprintpp-0.4.0.tar.gz", hash = "sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403"}, ] prompt-toolkit = [ - {file = "prompt_toolkit-3.0.19-py3-none-any.whl", hash = "sha256:7089d8d2938043508aa9420ec18ce0922885304cddae87fb96eebca942299f88"}, - {file = "prompt_toolkit-3.0.19.tar.gz", hash = "sha256:08360ee3a3148bdb5163621709ee322ec34fc4375099afa4bbf751e9b7b7fa4f"}, + {file = "prompt_toolkit-3.0.20-py3-none-any.whl", hash = "sha256:6076e46efae19b1e0ca1ec003ed37a933dc94b4d20f486235d436e64771dcd5c"}, + {file = "prompt_toolkit-3.0.20.tar.gz", hash = "sha256:eb71d5a6b72ce6db177af4a7d4d7085b99756bf656d98ffcc4fecd36850eea6c"}, ] ptyprocess = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, @@ -1244,8 +1184,8 @@ pyflakes = [ {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, ] pygments = [ - {file = "Pygments-2.9.0-py3-none-any.whl", hash = "sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e"}, - {file = "Pygments-2.9.0.tar.gz", hash = "sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f"}, + {file = "Pygments-2.10.0-py3-none-any.whl", hash = "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380"}, + {file = "Pygments-2.10.0.tar.gz", hash = "sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"}, ] pyparsing = [ {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, @@ -1289,26 +1229,18 @@ pyyaml = [ {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, @@ -1318,67 +1250,51 @@ pyyaml-env-tag = [ {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, ] regex = [ - {file = "regex-2021.7.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e6a1e5ca97d411a461041d057348e578dc344ecd2add3555aedba3b408c9f874"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:6afe6a627888c9a6cfbb603d1d017ce204cebd589d66e0703309b8048c3b0854"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ccb3d2190476d00414aab36cca453e4596e8f70a206e2aa8db3d495a109153d2"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:ed693137a9187052fc46eedfafdcb74e09917166362af4cc4fddc3b31560e93d"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:99d8ab206a5270c1002bfcf25c51bf329ca951e5a169f3b43214fdda1f0b5f0d"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:b85ac458354165405c8a84725de7bbd07b00d9f72c31a60ffbf96bb38d3e25fa"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:3f5716923d3d0bfb27048242a6e0f14eecdb2e2a7fac47eda1d055288595f222"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5983c19d0beb6af88cb4d47afb92d96751fb3fa1784d8785b1cdf14c6519407"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf1d2d183abc7faa101ebe0b8d04fd19cb9138820abc8589083035c9440b8ca6"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1947e7de155063e1c495c50590229fb98720d4c383af5031bbcb413db33fa1be"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:17d8a3f99b18d87ac54a449b836d485cc8c195bb6f5e4379c84c8519045facc9"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d30895ec80cc80358392841add9dde81ea1d54a4949049269115e6b0555d0498"}, - {file = "regex-2021.7.6-cp36-cp36m-win32.whl", hash = "sha256:c92831dac113a6e0ab28bc98f33781383fe294df1a2c3dfd1e850114da35fd5b"}, - {file = "regex-2021.7.6-cp36-cp36m-win_amd64.whl", hash = "sha256:791aa1b300e5b6e5d597c37c346fb4d66422178566bbb426dd87eaae475053fb"}, - {file = "regex-2021.7.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:59506c6e8bd9306cd8a41511e32d16d5d1194110b8cfe5a11d102d8b63cf945d"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:564a4c8a29435d1f2256ba247a0315325ea63335508ad8ed938a4f14c4116a5d"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:59c00bb8dd8775473cbfb967925ad2c3ecc8886b3b2d0c90a8e2707e06c743f0"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:9a854b916806c7e3b40e6616ac9e85d3cdb7649d9e6590653deb5b341a736cec"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:db2b7df831c3187a37f3bb80ec095f249fa276dbe09abd3d35297fc250385694"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:173bc44ff95bc1e96398c38f3629d86fa72e539c79900283afa895694229fe6a"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:15dddb19823f5147e7517bb12635b3c82e6f2a3a6b696cc3e321522e8b9308ad"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ddeabc7652024803666ea09f32dd1ed40a0579b6fbb2a213eba590683025895"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8244c681018423a0d1784bc6b9af33bdf55f2ab8acb1f3cd9dd83d90e0813253"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8a4c742089faf0e51469c6a1ad7e3d3d21afae54a16a6cead85209dfe0a1ce65"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:914e626dc8e75fe4fc9b7214763f141d9f40165d00dfe680b104fa1b24063bbf"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3fabb19c82ecf39832a3f5060dfea9a7ab270ef156039a1143a29a83a09a62de"}, - {file = "regex-2021.7.6-cp37-cp37m-win32.whl", hash = "sha256:f080248b3e029d052bf74a897b9d74cfb7643537fbde97fe8225a6467fb559b5"}, - {file = "regex-2021.7.6-cp37-cp37m-win_amd64.whl", hash = "sha256:d8bbce0c96462dbceaa7ac4a7dfbbee92745b801b24bce10a98d2f2b1ea9432f"}, - {file = "regex-2021.7.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:edd1a68f79b89b0c57339bce297ad5d5ffcc6ae7e1afdb10f1947706ed066c9c"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux1_i686.whl", hash = "sha256:422dec1e7cbb2efbbe50e3f1de36b82906def93ed48da12d1714cabcd993d7f0"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:cbe23b323988a04c3e5b0c387fe3f8f363bf06c0680daf775875d979e376bd26"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:0eb2c6e0fcec5e0f1d3bcc1133556563222a2ffd2211945d7b1480c1b1a42a6f"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:1c78780bf46d620ff4fff40728f98b8afd8b8e35c3efd638c7df67be2d5cddbf"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:bc84fb254a875a9f66616ed4538542fb7965db6356f3df571d783f7c8d256edd"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:598c0a79b4b851b922f504f9f39a863d83ebdfff787261a5ed061c21e67dd761"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875c355360d0f8d3d827e462b29ea7682bf52327d500a4f837e934e9e4656068"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfc0957c4a4b91eff5ad036088769e600a25774256cd0e1154378591ce573f08"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efb4af05fa4d2fc29766bf516f1f5098d6b5c3ed846fde980c18bf8646ad3979"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7423aca7cc30a6228ccdcf2ea76f12923d652c5c7c6dc1959a0b004e308f39fb"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bb9834c1e77493efd7343b8e38950dee9797d2d6f2d5fd91c008dfaef64684b9"}, - {file = "regex-2021.7.6-cp38-cp38-win32.whl", hash = "sha256:e586f448df2bbc37dfadccdb7ccd125c62b4348cb90c10840d695592aa1b29e0"}, - {file = "regex-2021.7.6-cp38-cp38-win_amd64.whl", hash = "sha256:2fe5e71e11a54e3355fa272137d521a40aace5d937d08b494bed4529964c19c4"}, - {file = "regex-2021.7.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6110bab7eab6566492618540c70edd4d2a18f40ca1d51d704f1d81c52d245026"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux1_i686.whl", hash = "sha256:4f64fc59fd5b10557f6cd0937e1597af022ad9b27d454e182485f1db3008f417"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:89e5528803566af4df368df2d6f503c84fbfb8249e6631c7b025fe23e6bd0cde"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2366fe0479ca0e9afa534174faa2beae87847d208d457d200183f28c74eaea59"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:f9392a4555f3e4cb45310a65b403d86b589adc773898c25a39184b1ba4db8985"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:2bceeb491b38225b1fee4517107b8491ba54fba77cf22a12e996d96a3c55613d"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:f98dc35ab9a749276f1a4a38ab3e0e2ba1662ce710f6530f5b0a6656f1c32b58"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:319eb2a8d0888fa6f1d9177705f341bc9455a2c8aca130016e52c7fe8d6c37a3"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:598ee917dbe961dcf827217bf2466bb86e4ee5a8559705af57cbabb3489dd37e"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:56fc7045a1999a8d9dd1896715bc5c802dfec5b9b60e883d2cbdecb42adedea4"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8363ac90ea63c3dd0872dfdb695f38aff3334bfa5712cffb238bd3ffef300e3"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:716a6db91b3641f566531ffcc03ceec00b2447f0db9942b3c6ea5d2827ad6be3"}, - {file = "regex-2021.7.6-cp39-cp39-win32.whl", hash = "sha256:eaf58b9e30e0e546cdc3ac06cf9165a1ca5b3de8221e9df679416ca667972035"}, - {file = "regex-2021.7.6-cp39-cp39-win_amd64.whl", hash = "sha256:4c9c3155fe74269f61e27617529b7f09552fbb12e44b1189cebbdb24294e6e1c"}, - {file = "regex-2021.7.6.tar.gz", hash = "sha256:8394e266005f2d8c6f0bc6780001f7afa3ef81a7a2111fa35058ded6fce79e4d"}, + {file = "regex-2021.9.30-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:66696c8336a1b5d1182464f3af3427cc760118f26d0b09a2ddc16a976a4d2637"}, + {file = "regex-2021.9.30-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d87459ad3ab40cd8493774f8a454b2e490d8e729e7e402a0625867a983e4e02"}, + {file = "regex-2021.9.30-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78cf6a1e023caf5e9a982f5377414e1aeac55198831b852835732cfd0a0ca5ff"}, + {file = "regex-2021.9.30-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:255791523f80ea8e48e79af7120b4697ef3b74f6886995dcdb08c41f8e516be0"}, + {file = "regex-2021.9.30-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e502f8d4e5ef714bcc2c94d499684890c94239526d61fdf1096547db91ca6aa6"}, + {file = "regex-2021.9.30-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4907fb0f9b9309a5bded72343e675a252c2589a41871874feace9a05a540241e"}, + {file = "regex-2021.9.30-cp310-cp310-win32.whl", hash = "sha256:3be40f720af170a6b20ddd2ad7904c58b13d2b56f6734ee5d09bbdeed2fa4816"}, + {file = "regex-2021.9.30-cp310-cp310-win_amd64.whl", hash = "sha256:c2b180ed30856dfa70cfe927b0fd38e6b68198a03039abdbeb1f2029758d87e7"}, + {file = "regex-2021.9.30-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e6f2d2f93001801296fe3ca86515eb04915472b5380d4d8752f09f25f0b9b0ed"}, + {file = "regex-2021.9.30-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fa7ba9ab2eba7284e0d7d94f61df7af86015b0398e123331362270d71fab0b9"}, + {file = "regex-2021.9.30-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28040e89a04b60d579c69095c509a4f6a1a5379cd865258e3a186b7105de72c6"}, + {file = "regex-2021.9.30-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f588209d3e4797882cd238195c175290dbc501973b10a581086b5c6bcd095ffb"}, + {file = "regex-2021.9.30-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42952d325439ef223e4e9db7ee6d9087b5c68c5c15b1f9de68e990837682fc7b"}, + {file = "regex-2021.9.30-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cae4099031d80703954c39680323dabd87a69b21262303160776aa0e55970ca0"}, + {file = "regex-2021.9.30-cp36-cp36m-win32.whl", hash = "sha256:0de8ad66b08c3e673b61981b9e3626f8784d5564f8c3928e2ad408c0eb5ac38c"}, + {file = "regex-2021.9.30-cp36-cp36m-win_amd64.whl", hash = "sha256:b345ecde37c86dd7084c62954468a4a655fd2d24fd9b237949dd07a4d0dd6f4c"}, + {file = "regex-2021.9.30-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6f08187136f11e430638c2c66e1db091105d7c2e9902489f0dbc69b44c222b4"}, + {file = "regex-2021.9.30-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b55442650f541d195a535ccec33078c78a9521973fb960923da7515e9ed78fa6"}, + {file = "regex-2021.9.30-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87e9c489aa98f50f367fb26cc9c8908d668e9228d327644d7aa568d47e456f47"}, + {file = "regex-2021.9.30-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e2cb7d4909ed16ed35729d38af585673f1f0833e73dfdf0c18e5be0061107b99"}, + {file = "regex-2021.9.30-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0861e7f6325e821d5c40514c551fd538b292f8cc3960086e73491b9c5d8291d"}, + {file = "regex-2021.9.30-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:81fdc90f999b2147fc62e303440c424c47e5573a9b615ed5d43a5b832efcca9e"}, + {file = "regex-2021.9.30-cp37-cp37m-win32.whl", hash = "sha256:8c1ad61fa024195136a6b7b89538030bd00df15f90ac177ca278df9b2386c96f"}, + {file = "regex-2021.9.30-cp37-cp37m-win_amd64.whl", hash = "sha256:e3770781353a4886b68ef10cec31c1f61e8e3a0be5f213c2bb15a86efd999bc4"}, + {file = "regex-2021.9.30-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9c065d95a514a06b92a5026766d72ac91bfabf581adb5b29bc5c91d4b3ee9b83"}, + {file = "regex-2021.9.30-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9925985be05d54b3d25fd6c1ea8e50ff1f7c2744c75bdc4d3b45c790afa2bcb3"}, + {file = "regex-2021.9.30-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:470f2c882f2672d8eeda8ab27992aec277c067d280b52541357e1acd7e606dae"}, + {file = "regex-2021.9.30-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ad0517df22a97f1da20d8f1c8cb71a5d1997fa383326b81f9cf22c9dadfbdf34"}, + {file = "regex-2021.9.30-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9e30838df7bfd20db6466fd309d9b580d32855f8e2c2e6d74cf9da27dcd9b63"}, + {file = "regex-2021.9.30-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5b34d2335d6aedec7dcadd3f8283b9682fadad8b9b008da8788d2fce76125ebe"}, + {file = "regex-2021.9.30-cp38-cp38-win32.whl", hash = "sha256:e07049cece3462c626d650e8bf42ddbca3abf4aa08155002c28cb6d9a5a281e2"}, + {file = "regex-2021.9.30-cp38-cp38-win_amd64.whl", hash = "sha256:37868075eda024470bd0feab872c692ac4ee29db1e14baec103257bf6cc64346"}, + {file = "regex-2021.9.30-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d331f238a7accfbbe1c4cd1ba610d4c087b206353539331e32a8f05345c74aec"}, + {file = "regex-2021.9.30-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6348a7ab2a502cbdd0b7fd0496d614007489adb7361956b38044d1d588e66e04"}, + {file = "regex-2021.9.30-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce7b1cca6c23f19bee8dc40228d9c314d86d1e51996b86f924aca302fc8f8bf9"}, + {file = "regex-2021.9.30-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1f1125bc5172ab3a049bc6f4b9c0aae95a2a2001a77e6d6e4239fa3653e202b5"}, + {file = "regex-2021.9.30-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:638e98d069b14113e8afba6a54d1ca123f712c0d105e67c1f9211b2a825ef926"}, + {file = "regex-2021.9.30-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9a0b0db6b49da7fa37ca8eddf9f40a8dbc599bad43e64f452284f37b6c34d91c"}, + {file = "regex-2021.9.30-cp39-cp39-win32.whl", hash = "sha256:9910869c472e5a6728680ca357b5846546cbbd2ab3ad5bef986ef0bc438d0aa6"}, + {file = "regex-2021.9.30-cp39-cp39-win_amd64.whl", hash = "sha256:3b71213ec3bad9a5a02e049f2ec86b3d7c3e350129ae0f4e2f99c12b5da919ed"}, + {file = "regex-2021.9.30.tar.gz", hash = "sha256:81e125d9ba54c34579e4539a967e976a3c56150796674aec318b1b2f49251be7"}, ] rich = [ - {file = "rich-10.6.0-py3-none-any.whl", hash = "sha256:d3f72827cd5df13b2ef7f1a97f81ec65548d4fdeb92cef653234f227580bbb2a"}, - {file = "rich-10.6.0.tar.gz", hash = "sha256:128261b3e2419a4ef9c97066ccc2abbfb49fa7c5e89c3fe4056d00aa5e9c1e65"}, + {file = "rich-10.11.0-py3-none-any.whl", hash = "sha256:44bb3f9553d00b3c8938abf89828df870322b9ba43caf3b12bb7758debdc6dec"}, + {file = "rich-10.11.0.tar.gz", hash = "sha256:016fa105f34b69c434e7f908bb5bd7fefa9616efdb218a2917117683a6394ce5"}, ] secretstorage = [ {file = "SecretStorage-3.3.1-py3-none-any.whl", hash = "sha256:422d82c36172d88d6a0ed5afdec956514b189ddbfb72fefab0c8a1cee4eaf71f"}, @@ -1397,12 +1313,12 @@ toml = [ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] tomli = [ - {file = "tomli-1.0.4-py3-none-any.whl", hash = "sha256:0713b16ff91df8638a6a694e295c8159ab35ba93e3424a626dd5226d386057be"}, - {file = "tomli-1.0.4.tar.gz", hash = "sha256:be670d0d8d7570fd0ea0113bd7bb1ba3ac6706b4de062cc4c952769355c9c268"}, + {file = "tomli-1.2.1-py3-none-any.whl", hash = "sha256:8dd0e9524d6f386271a36b41dbf6c57d8e32fd96fd22b6584679dc569d20899f"}, + {file = "tomli-1.2.1.tar.gz", hash = "sha256:a5b75cb6f3968abb47af1b40c1819dc519ea82bcc065776a866e8d74c5ca9442"}, ] traitlets = [ - {file = "traitlets-5.0.5-py3-none-any.whl", hash = "sha256:69ff3f9d5351f31a7ad80443c2674b7099df13cc41fc5fa6e2f6d3b0330b0426"}, - {file = "traitlets-5.0.5.tar.gz", hash = "sha256:178f4ce988f69189f7e523337a3e11d91c786ded9360174a3d9ca83e79bc5396"}, + {file = "traitlets-5.1.0-py3-none-any.whl", hash = "sha256:03f172516916220b58c9f19d7f854734136dd9528103d04e9bf139a92c9f54c4"}, + {file = "traitlets-5.1.0.tar.gz", hash = "sha256:bd382d7ea181fbbcce157c133db9a829ce06edffe097bcf3ab945b435452b46d"}, ] typed-ast = [ {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"}, @@ -1446,27 +1362,29 @@ tzlocal = [ {file = "tzlocal-2.1.tar.gz", hash = "sha256:643c97c5294aedc737780a49d9df30889321cbe1204eac2c2ec6134035a92e44"}, ] watchdog = [ - {file = "watchdog-2.1.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9628f3f85375a17614a2ab5eac7665f7f7be8b6b0a2a228e6f6a2e91dd4bfe26"}, - {file = "watchdog-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:acc4e2d5be6f140f02ee8590e51c002829e2c33ee199036fcd61311d558d89f4"}, - {file = "watchdog-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:85b851237cf3533fabbc034ffcd84d0fa52014b3121454e5f8b86974b531560c"}, - {file = "watchdog-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a12539ecf2478a94e4ba4d13476bb2c7a2e0a2080af2bb37df84d88b1b01358a"}, - {file = "watchdog-2.1.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6fe9c8533e955c6589cfea6f3f0a1a95fb16867a211125236c82e1815932b5d7"}, - {file = "watchdog-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d9456f0433845e7153b102fffeb767bde2406b76042f2216838af3b21707894e"}, - {file = "watchdog-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fd8c595d5a93abd441ee7c5bb3ff0d7170e79031520d113d6f401d0cf49d7c8f"}, - {file = "watchdog-2.1.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0bcfe904c7d404eb6905f7106c54873503b442e8e918cc226e1828f498bdc0ca"}, - {file = "watchdog-2.1.3-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bf84bd94cbaad8f6b9cbaeef43080920f4cb0e61ad90af7106b3de402f5fe127"}, - {file = "watchdog-2.1.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b8ddb2c9f92e0c686ea77341dcb58216fa5ff7d5f992c7278ee8a392a06e86bb"}, - {file = "watchdog-2.1.3-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8805a5f468862daf1e4f4447b0ccf3acaff626eaa57fbb46d7960d1cf09f2e6d"}, - {file = "watchdog-2.1.3-py3-none-manylinux2014_armv7l.whl", hash = "sha256:3e305ea2757f81d8ebd8559d1a944ed83e3ab1bdf68bcf16ec851b97c08dc035"}, - {file = "watchdog-2.1.3-py3-none-manylinux2014_i686.whl", hash = "sha256:431a3ea70b20962e6dee65f0eeecd768cd3085ea613ccb9b53c8969de9f6ebd2"}, - {file = "watchdog-2.1.3-py3-none-manylinux2014_ppc64.whl", hash = "sha256:e4929ac2aaa2e4f1a30a36751160be391911da463a8799460340901517298b13"}, - {file = "watchdog-2.1.3-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:201cadf0b8c11922f54ec97482f95b2aafca429c4c3a4bb869a14f3c20c32686"}, - {file = "watchdog-2.1.3-py3-none-manylinux2014_s390x.whl", hash = "sha256:3a7d242a7963174684206093846537220ee37ba9986b824a326a8bb4ef329a33"}, - {file = "watchdog-2.1.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:54e057727dd18bd01a3060dbf5104eb5a495ca26316487e0f32a394fd5fe725a"}, - {file = "watchdog-2.1.3-py3-none-win32.whl", hash = "sha256:b5fc5c127bad6983eecf1ad117ab3418949f18af9c8758bd10158be3647298a9"}, - {file = "watchdog-2.1.3-py3-none-win_amd64.whl", hash = "sha256:44acad6f642996a2b50bb9ce4fb3730dde08f23e79e20cd3d8e2a2076b730381"}, - {file = "watchdog-2.1.3-py3-none-win_ia64.whl", hash = "sha256:0bcdf7b99b56a3ae069866c33d247c9994ffde91b620eaf0306b27e099bd1ae0"}, - {file = "watchdog-2.1.3.tar.gz", hash = "sha256:e5236a8e8602ab6db4b873664c2d356c365ab3cac96fbdec4970ad616415dd45"}, + {file = "watchdog-2.1.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9693f35162dc6208d10b10ddf0458cc09ad70c30ba689d9206e02cd836ce28a3"}, + {file = "watchdog-2.1.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:aba5c812f8ee8a3ff3be51887ca2d55fb8e268439ed44110d3846e4229eb0e8b"}, + {file = "watchdog-2.1.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4ae38bf8ba6f39d5b83f78661273216e7db5b00f08be7592062cb1fc8b8ba542"}, + {file = "watchdog-2.1.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ad6f1796e37db2223d2a3f302f586f74c72c630b48a9872c1e7ae8e92e0ab669"}, + {file = "watchdog-2.1.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:922a69fa533cb0c793b483becaaa0845f655151e7256ec73630a1b2e9ebcb660"}, + {file = "watchdog-2.1.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b2fcf9402fde2672545b139694284dc3b665fd1be660d73eca6805197ef776a3"}, + {file = "watchdog-2.1.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3386b367e950a11b0568062b70cc026c6f645428a698d33d39e013aaeda4cc04"}, + {file = "watchdog-2.1.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f1c00aa35f504197561060ca4c21d3cc079ba29cf6dd2fe61024c70160c990b"}, + {file = "watchdog-2.1.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b52b88021b9541a60531142b0a451baca08d28b74a723d0c99b13c8c8d48d604"}, + {file = "watchdog-2.1.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8047da932432aa32c515ec1447ea79ce578d0559362ca3605f8e9568f844e3c6"}, + {file = "watchdog-2.1.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e92c2d33858c8f560671b448205a268096e17870dcf60a9bb3ac7bfbafb7f5f9"}, + {file = "watchdog-2.1.6-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b7d336912853d7b77f9b2c24eeed6a5065d0a0cc0d3b6a5a45ad6d1d05fb8cd8"}, + {file = "watchdog-2.1.6-py3-none-manylinux2014_aarch64.whl", hash = "sha256:cca7741c0fcc765568350cb139e92b7f9f3c9a08c4f32591d18ab0a6ac9e71b6"}, + {file = "watchdog-2.1.6-py3-none-manylinux2014_armv7l.whl", hash = "sha256:25fb5240b195d17de949588628fdf93032ebf163524ef08933db0ea1f99bd685"}, + {file = "watchdog-2.1.6-py3-none-manylinux2014_i686.whl", hash = "sha256:be9be735f827820a06340dff2ddea1fb7234561fa5e6300a62fe7f54d40546a0"}, + {file = "watchdog-2.1.6-py3-none-manylinux2014_ppc64.whl", hash = "sha256:d0d19fb2441947b58fbf91336638c2b9f4cc98e05e1045404d7a4cb7cddc7a65"}, + {file = "watchdog-2.1.6-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:3becdb380d8916c873ad512f1701f8a92ce79ec6978ffde92919fd18d41da7fb"}, + {file = "watchdog-2.1.6-py3-none-manylinux2014_s390x.whl", hash = "sha256:ae67501c95606072aafa865b6ed47343ac6484472a2f95490ba151f6347acfc2"}, + {file = "watchdog-2.1.6-py3-none-manylinux2014_x86_64.whl", hash = "sha256:e0f30db709c939cabf64a6dc5babb276e6d823fd84464ab916f9b9ba5623ca15"}, + {file = "watchdog-2.1.6-py3-none-win32.whl", hash = "sha256:e02794ac791662a5eafc6ffeaf9bcc149035a0e48eb0a9d40a8feb4622605a3d"}, + {file = "watchdog-2.1.6-py3-none-win_amd64.whl", hash = "sha256:bd9ba4f332cf57b2c1f698be0728c020399ef3040577cde2939f2e045b39c1e5"}, + {file = "watchdog-2.1.6-py3-none-win_ia64.whl", hash = "sha256:a0f1c7edf116a12f7245be06120b1852275f9506a7d90227648b250755a03923"}, + {file = "watchdog-2.1.6.tar.gz", hash = "sha256:a36e75df6c767cbf46f61a91c70b3ba71811dfa0aca4a324d9407a06a8b7a2e7"}, ] wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, @@ -1481,6 +1399,6 @@ yq = [ {file = "yq-2.12.2.tar.gz", hash = "sha256:2f156d0724b61487ac8752ed4eaa702a5737b804d5afa46fa55866951cd106d2"}, ] zipp = [ - {file = "zipp-3.5.0-py3-none-any.whl", hash = "sha256:957cfda87797e389580cb8b9e3870841ca991e2125350677b2ca83a0e99390a3"}, - {file = "zipp-3.5.0.tar.gz", hash = "sha256:f5812b1e007e48cff63449a5e9f4e7ebea716b4111f9c4f9a645f91d579bf0c4"}, + {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, + {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"}, ] diff --git a/pyproject.toml b/pyproject.toml index b81e051b..098211e4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,13 +47,11 @@ tzlocal = ">2.0, <3.0" # https://github.com/regebro/tzlocal/blob/master/CHANGE # I don't like repeating deps here, but # there's no other way to do this yet until poetry v1.2 releases # see: https://github.com/python-poetry/poetry/issues/1644 -behave = { version = "^1.2", optional = true } pytest = { version = ">=6.2", optional = true } pytest-bdd = { version = ">=4.0.1", optional = true } toml = { version = ">=0.10", optional = true } [tool.poetry.dev-dependencies] -behave = "^1.2" mkdocs = ">=1.0" black = { version = ">=21.5b2", allow-prereleases = true } toml = ">=0.10" @@ -65,7 +63,7 @@ pyproject-flake8 = "*" yq = "*" [tool.poetry.extras] -testing = [ "behave", "pytest", "pytest-bdd", "toml" ] +testing = [ "pytest", "pytest-bdd", "toml" ] [tool.poetry.scripts] jrnl = 'jrnl.cli:cli' diff --git a/tests/bdd/features/override.feature b/tests/bdd/features/override.feature index 3d9fb27f..b29b11f0 100644 --- a/tests/bdd/features/override.feature +++ b/tests/bdd/features/override.feature @@ -8,13 +8,11 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys And the editor should not have been called - # @todo implement this step in pytest (doesn't currently support overrides) - @skip 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 should contain "highlight: false" + Then the config in memory should contain "highlight: false" Then the editor should not have been called @@ -38,23 +36,24 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys ┖─────────────────────┘ - # @todo implement this step in pytest (doesn't currently support overrides) - @skip 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 should have "colors.body" set to "blue" + Then the config in memory should contain "colors.body: blue" - # @todo implement this step in pytest (doesn't currently support overrides) - @skip 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 should have "colors.body" set to "green" - And the config should have "editor" set to "nano" + Then the config in memory should contain + editor: nano + colors: + title: none + body: green + tags: none + date: none Scenario: Override default journal diff --git a/tests/lib/fixtures.py b/tests/lib/fixtures.py index a93a7e43..1b4c74dc 100644 --- a/tests/lib/fixtures.py +++ b/tests/lib/fixtures.py @@ -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 diff --git a/tests/lib/helpers.py b/tests/lib/helpers.py index 7d089597..2e1f454a 100644 --- a/tests/lib/helpers.py +++ b/tests/lib/helpers.py @@ -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 diff --git a/tests/lib/then_steps.py b/tests/lib/then_steps.py index 2dadf82e..627cb323 100644 --- a/tests/lib/then_steps.py +++ b/tests/lib/then_steps.py @@ -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") @@ -110,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: @@ -129,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 @@ -145,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"], "." @@ -161,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, ".") diff --git a/tests/lib/when_steps.py b/tests/lib/when_steps.py index 642249e9..80d8a7fb 100644 --- a/tests/lib/when_steps.py +++ b/tests/lib/when_steps.py @@ -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( diff --git a/tests/unit/test_override.py b/tests/unit/test_override.py index d22709f4..2719e884 100644 --- a/tests/unit/test_override.py +++ b/tests/unit/test_override.py @@ -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(): From d347dac19e7e37ad644cd5678ef9a03f7453094d Mon Sep 17 00:00:00 2001 From: Jrnl Bot Date: Sat, 9 Oct 2021 19:11:41 +0000 Subject: [PATCH 215/215] Update changelog [ci skip] --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c47711d7..385e1622 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.8.3...HEAD) +**Build:** + +- Add more steps to `pytest`, fully remove `behave` [\#1347](https://github.com/jrnl-org/jrnl/pull/1347) ([wren](https://github.com/wren)) + **Documentation:** - Document folder journal and DayOne journal types [\#1326](https://github.com/jrnl-org/jrnl/issues/1326)