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/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 339b47ba..00000000 Binary files a/features/data/journals/encrypted_jrnl-1-9-5.journal and /dev/null differ 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/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..74f6291b 100644 --- a/jrnl/FolderJournal.py +++ b/jrnl/FolderJournal.py @@ -22,10 +22,11 @@ def get_files(journal_config): class Folder(Journal.Journal): """A Journal handling multiple files in a folder""" - def __init__(self, **kwargs): + def __init__(self, name="default", **kwargs): self.entries = [] self._diff_entry_dates = [] - super(Folder, self).__init__(**kwargs) + self.can_be_encrypted = False + super().__init__(name, **kwargs) def open(self): filenames = [] @@ -43,10 +44,12 @@ class Folder(Journal.Journal): # Create a list of dates of modified entries. Start with diff_entry_dates modified_dates = self._diff_entry_dates seen_dates = set(self._diff_entry_dates) + for e in self.entries: if e.modified: - if e.date not in seen_dates: + if e.date not in modified_dates: modified_dates.append(e.date) + if e.date not in seen_dates: seen_dates.add(e.date) # For every date that had a modified entry, write to a file @@ -80,8 +83,14 @@ class Folder(Journal.Journal): # print("empty file: {}".format(filename)) os.remove(filename) + def delete_entries(self, entries_to_delete): + """Deletes specific entries from a journal.""" + for entry in entries_to_delete: + self.entries.remove(entry) + self._diff_entry_dates.append(entry.date) + def parse_editable_str(self, edited): - """Parses the output of self.editable_str and updates it's entries.""" + """Parses the output of self.editable_str and updates its entries.""" mod_entries = self._parse(edited) diff_entries = set(self.entries) - set(mod_entries) for e in diff_entries: diff --git a/jrnl/Journal.py b/jrnl/Journal.py index 6d3c6886..17de129f 100644 --- a/jrnl/Journal.py +++ b/jrnl/Journal.py @@ -67,9 +67,11 @@ class Journal: return new_journal def import_(self, other_journal_txt): - self.entries = list( - frozenset(self.entries) | frozenset(self._parse(other_journal_txt)) - ) + imported_entries = self._parse(other_journal_txt) + for entry in imported_entries: + entry.modified = True + + self.entries = list(frozenset(self.entries) | frozenset(imported_entries)) self.sort() def open(self, filename=None): @@ -405,6 +407,12 @@ def open_journal(journal_name, config, legacy=False): config["journal"] = os.path.expanduser(os.path.expandvars(config["journal"])) if os.path.isdir(config["journal"]): + if config["encrypt"]: + print( + "Warning: This journal's config has 'encrypt' set to true, but this type of journal can't be encrypted.", + file=sys.stderr, + ) + if config["journal"].strip("/").endswith(".dayone") or "entries" in os.listdir( config["journal"] ): @@ -414,7 +422,7 @@ def open_journal(journal_name, config, legacy=False): else: from . import FolderJournal - return FolderJournal.Folder(**config).open() + return FolderJournal.Folder(journal_name, **config).open() if not config["encrypt"]: if legacy: diff --git a/jrnl/__version__.py b/jrnl/__version__.py index 51977ba3..e0822e62 100644 --- a/jrnl/__version__.py +++ b/jrnl/__version__.py @@ -1 +1 @@ -__version__ = "v2.8.1" +__version__ = "v2.8.3" 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 """, 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/config.py b/jrnl/config.py index 32695204..a0482405 100644 --- a/jrnl/config.py +++ b/jrnl/config.py @@ -20,6 +20,7 @@ DEFAULT_JOURNAL_NAME = "journal.txt" DEFAULT_JOURNAL_KEY = "default" YAML_SEPARATOR = ": " +YAML_FILE_ENCODING = "utf-8" def make_yaml_valid_dict(input: list) -> dict: @@ -48,9 +49,13 @@ def make_yaml_valid_dict(input: list) -> dict: def save_config(config): config["version"] = __version__ - with open(get_config_path(), "w") as f: + with open(get_config_path(), "w", encoding=YAML_FILE_ENCODING) as f: yaml.safe_dump( - config, f, encoding="utf-8", allow_unicode=True, default_flow_style=False + config, + f, + encoding=YAML_FILE_ENCODING, + allow_unicode=True, + default_flow_style=False, ) @@ -139,7 +144,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: + with open(config_path, encoding=YAML_FILE_ENCODING) as f: return yaml.load(f, Loader=yaml.SafeLoader) 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/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/mkdocs.yml b/mkdocs.yml index bf45a393..5515d0fa 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -22,6 +22,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 diff --git a/poetry.lock b/poetry.lock index 94b251d3..8c86d892 100644 --- a/poetry.lock +++ b/poetry.lock @@ -9,14 +9,6 @@ python-versions = "*" [package.dependencies] textwrap3 = ">=0.9.2" -[[package]] -name = "appdirs" -version = "1.4.4" -description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" -optional = false -python-versions = "*" - [[package]] name = "appnope" version = "0.1.2" @@ -77,44 +69,31 @@ 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.7b0" +version = "21.9b0" description = "The uncompromising code formatter." category = "dev" optional = false python-versions = ">=3.6.2" [package.dependencies] -appdirs = "*" click = ">=7.1.2" mypy-extensions = ">=0.4.3" -pathspec = ">=0.8.1,<1" +pathspec = ">=0.9.0,<1" +platformdirs = ">=2" regex = ">=2020.1.8" 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\""} +typing-extensions = [ + {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}, + {version = "!=3.10.0.1", markers = "python_version >= \"3.10\""}, +] [package.extras] colorama = ["colorama (>=0.4.3)"] d = ["aiohttp (>=3.6.0)", "aiohttp-cors (>=0.4.0)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] python2 = ["typed-ast (>=1.4.2)"] uvloop = ["uvloop (>=0.15.2)"] @@ -162,7 +141,7 @@ test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] [[package]] name = "cryptography" -version = "3.4.7" +version = "35.0.0" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false @@ -175,13 +154,13 @@ 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" -version = "5.0.9" +version = "5.1.0" description = "Decorators for Humans" category = "dev" optional = false @@ -203,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 @@ -213,7 +192,7 @@ python-versions = "*" python-dateutil = ">=2.8.1" [package.extras] -dev = ["twine", "markdown", "flake8"] +dev = ["twine", "markdown", "flake8", "wheel"] [[package]] name = "glob2" @@ -225,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 @@ -263,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 @@ -293,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" @@ -318,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]] @@ -344,7 +315,7 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "keyring" -version = "23.0.1" +version = "23.2.1" description = "Store and access your passwords safely." category = "main" optional = false @@ -362,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 @@ -399,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 @@ -426,7 +397,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 @@ -512,11 +483,11 @@ testing = ["docopt", "pytest (<6.0.0)"] [[package]] name = "pathspec" -version = "0.8.1" +version = "0.9.0" description = "Utility library for gitignore style pattern matching of file paths." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [[package]] name = "pexpect" @@ -537,19 +508,32 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "platformdirs" +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 +python-versions = ">=3.6" + +[package.extras] +docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] +test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] + [[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" @@ -561,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 = "*" @@ -612,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 @@ -640,7 +624,7 @@ toml = "*" [[package]] name = "pytest" -version = "6.2.4" +version = "6.2.5" description = "pytest: simple powerful testing with Python" category = "main" optional = false @@ -653,7 +637,7 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<1.0.0a1" +pluggy = ">=0.12,<2.0" py = ">=1.8.2" toml = "*" @@ -702,7 +686,7 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2021.1" +version = "2021.3" description = "World timezone definitions, modern and historical" category = "main" optional = false @@ -745,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 @@ -753,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 @@ -806,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 @@ -814,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"] @@ -836,7 +817,7 @@ python-versions = "*" [[package]] name = "typing-extensions" -version = "3.10.0.0" +version = "3.10.0.2" description = "Backported and Experimental Type Hints for Python 3.5+" category = "main" optional = false @@ -855,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" @@ -899,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 @@ -910,22 +891,18 @@ 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 = [ {file = "ansiwrap-0.8.4-py2.py3-none-any.whl", hash = "sha256:7b053567c88e1ad9eed030d3ac41b722125e4c1271c8a99ade797faff1f49fb1"}, {file = "ansiwrap-0.8.4.zip", hash = "sha256:ca0c740734cde59bf919f8ff2c386f74f9a369818cdc60efe94893d01ea8d9b7"}, ] -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"}, @@ -949,13 +926,9 @@ 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.7b0-py3-none-any.whl", hash = "sha256:1c7aa6ada8ee864db745b22790a32f94b2795c253a75d6d9b5e439ff10d23116"}, - {file = "black-21.7b0.tar.gz", hash = "sha256:c8373c6491de9362e39271630b65b964607bc5c79c83783547d76c839b3aa219"}, + {file = "black-21.9b0-py3-none-any.whl", hash = "sha256:380f1b5da05e5a1429225676655dddb96f5ae8c75bdf91e53d798871b902a115"}, + {file = "black-21.9b0.tar.gz", hash = "sha256:7de4cfc7eb6b710de325712d40125689101d21d25283eed7e9998722cf10eb91"}, ] cffi = [ {file = "cffi-1.14.6-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:22b9c3c320171c108e903d61a3723b51e37aaa8c81255b5e7ce102775bd01e2c"}, @@ -965,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"}, @@ -1017,36 +985,45 @@ commonmark = [ {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"}, - {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"}, + {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"}, - {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.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"}, @@ -1056,32 +1033,28 @@ 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"}, {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.2.1-py3-none-any.whl", hash = "sha256:bd2145a237ed70c8ce72978b497619ddfcae640b6dcf494402d5143e37755c6e"}, + {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"}, @@ -1124,8 +1097,8 @@ markupsafe = [ {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"}, @@ -1136,8 +1109,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"}, @@ -1163,8 +1136,8 @@ parso = [ {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"}, + {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, + {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, ] pexpect = [ {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, @@ -1174,17 +1147,21 @@ pickleshare = [ {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] +platformdirs = [ + {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"}, @@ -1207,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"}, @@ -1219,8 +1196,8 @@ pyproject-flake8 = [ {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"}, + {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, + {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, ] pytest-bdd = [ {file = "pytest-bdd-4.1.0.tar.gz", hash = "sha256:304cd2b09923b838d0c2f08331d1f4236a14ef3594efa94e3bdae0f384d3fa5d"}, @@ -1234,8 +1211,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"}, @@ -1252,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"}, @@ -1281,51 +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-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"}, + {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"}, @@ -1344,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"}, @@ -1384,36 +1353,38 @@ 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"}, ] 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.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"}, @@ -1428,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 5c6d5cbd..098211e4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "jrnl" -version = "v2.8.1" +version = "v2.8.3" description = "Collect your thoughts and notes without leaving the command line." authors = [ "jrnl contributors ", @@ -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 } +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/delete.feature b/tests/bdd/features/delete.feature index f46ef866..cfbe08ee 100644 --- a/tests/bdd/features/delete.feature +++ b/tests/bdd/features/delete.feature @@ -17,8 +17,8 @@ Feature: Delete entries from journal | config_file | | basic_onefile.yaml | | basic_encrypted.yaml | - # | basic_folder.yaml | @todo - # | basic_dayone.yaml | @todo + | basic_folder.yaml | + # | basic_dayone.yaml | @todo Scenario Outline: Backing out of interactive delete does not change journal @@ -66,7 +66,7 @@ Feature: Delete entries from journal Examples: Configs | config_file | | basic_onefile.yaml | - # | basic_folder.yaml | @todo + | basic_folder.yaml | # | basic_dayone.yaml | @todo @@ -82,7 +82,7 @@ Feature: Delete entries from journal Examples: Configs | config_file | | basic_onefile.yaml | - # | basic_folder.yaml | @todo + | basic_folder.yaml | # | basic_dayone.yaml | @todo @@ -98,7 +98,7 @@ Feature: Delete entries from journal Examples: Configs | config_file | | basic_onefile.yaml | - # | basic_folder.yaml | @todo + | basic_folder.yaml | # | basic_dayone.yaml | @todo @@ -114,7 +114,7 @@ Feature: Delete entries from journal Examples: Configs | config_file | | basic_onefile.yaml | - # | basic_folder.yaml | @todo + | basic_folder.yaml | # | basic_dayone.yaml | @todo @@ -130,7 +130,7 @@ Feature: Delete entries from journal Examples: Configs | config_file | | basic_onefile.yaml | - # | basic_folder.yaml | @todo + | basic_folder.yaml | # | basic_dayone.yaml | @todo @@ -146,7 +146,7 @@ Feature: Delete entries from journal Examples: Configs | config_file | | basic_onefile.yaml | - # | basic_folder.yaml | @todo + | basic_folder.yaml | # | basic_dayone.yaml | @todo @@ -162,7 +162,7 @@ Feature: Delete entries from journal Examples: Configs | config_file | | basic_onefile.yaml | - # | basic_folder.yaml | @todo + | basic_folder.yaml | # | basic_dayone.yaml | @todo @@ -178,5 +178,5 @@ Feature: Delete entries from journal Examples: Configs | config_file | | basic_onefile.yaml | - # | basic_folder.yaml | @todo + | basic_folder.yaml | # | basic_dayone.yaml | @todo diff --git a/tests/bdd/features/encrypt.feature b/tests/bdd/features/encrypt.feature index 31d53520..af141172 100644 --- a/tests/bdd/features/encrypt.feature +++ b/tests/bdd/features/encrypt.feature @@ -28,15 +28,37 @@ Feature: Encrypting and decrypting journals # This should warn the user that the journal is already encrypted - Scenario: Encrypting a journal + Scenario Outline: Encrypting a journal Given we use the config "simple.yaml" When we run "jrnl --encrypt" and enter swordfish swordfish n - Then we should see the message "Journal encrypted" + Then we should get no error + And we should see the message "Journal encrypted" And the config for journal "default" should contain "encrypt: true" When we run "jrnl -n 1" and enter "swordfish" Then we should be prompted for a password And the output should contain "2013-06-10 15:40 Life is good" + + Scenario Outline: Running jrnl with encrypt: true on unencryptable journals + Given we use the config "" + When we run "jrnl --config-override encrypt true here is a new entry" + Then the error output should contain "this type of journal can't be encrypted" + + Examples: configs + | config_file | + | basic_folder.yaml | + | basic_dayone.yaml | + + + Scenario Outline: Attempt to encrypt a folder or DayOne journal should result in an error + Given we use the config "" + 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 | 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/import.feature b/tests/bdd/features/import.feature index d75d6017..920cddf2 100644 --- a/tests/bdd/features/import.feature +++ b/tests/bdd/features/import.feature @@ -11,7 +11,7 @@ Feature: Importing data | config_file | | basic_onefile.yaml | | basic_encrypted.yaml | - # | basic_folder.yaml | @todo + | basic_folder.yaml | # | basic_dayone.yaml | @todo Scenario Outline: --import allows new large entry from stdin @@ -34,7 +34,7 @@ Feature: Importing data | config_file | | basic_onefile.yaml | | basic_encrypted.yaml | - # | basic_folder.yaml | @todo + | basic_folder.yaml | # | basic_dayone.yaml | @todo Scenario Outline: --import allows multiple new entries from stdin @@ -56,7 +56,7 @@ Feature: Importing data | config_file | | basic_onefile.yaml | | basic_encrypted.yaml | - # | basic_folder.yaml | @todo + | basic_folder.yaml | # | basic_dayone.yaml | @todo Scenario: --import allows import new entries from file diff --git a/tests/bdd/features/multiple_journals.feature b/tests/bdd/features/multiple_journals.feature index cd531ee2..381463bf 100644 --- a/tests/bdd/features/multiple_journals.feature +++ b/tests/bdd/features/multiple_journals.feature @@ -88,3 +88,9 @@ Feature: Multiple journals these three eyes n Then the output should contain "Encrypted journal 'new_encrypted' created" + + Scenario: Read and write to journal with emoji name + Given we use the config "multiple.yaml" + When we run "jrnl โœจ Adding entry to sparkly journal" + When we run "jrnl โœจ -1" + Then the output should contain "Adding entry to sparkly journal" diff --git a/tests/bdd/features/override.feature b/tests/bdd/features/override.feature new file mode 100644 index 00000000..b29b11f0 --- /dev/null +++ b/tests/bdd/features/override.feature @@ -0,0 +1,90 @@ +Feature: Implementing Runtime Overrides for Select Configuration Keys + + Scenario: Override configured editor with built-in input === editor:'' + Given we use the config "basic_encrypted.yaml" + And we use the password "test" if prompted + When we run "jrnl --config-override editor ''" + Then the stdin prompt should have been called + And the editor should not have been called + + + Scenario: Postconfig commands with overrides + Given we use the config "basic_encrypted.yaml" + And we use the password "test" if prompted + When we run "jrnl --decrypt --config-override highlight false --config-override editor nano" + Then the config in memory should contain "highlight: false" + Then the editor should not have been called + + + Scenario: Override configured linewrap with a value of 23 + Given we use the config "simple.yaml" + And we use the password "test" if prompted + When we run "jrnl -2 --config-override linewrap 23 --format fancy" + Then the output should be + โ”Žโ”€โ”€โ”€โ”€โ”€โ•ฎ2013-06-09 15:39 + โ”ƒ My โ•˜โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•• + โ”ƒ fir st ent ry. โ”‚ + โ” โ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ”ค + โ”ƒ Everything is โ”‚ + โ”ƒ alright โ”‚ + โ”–โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”Žโ”€โ”€โ”€โ”€โ”€โ•ฎ2013-06-10 15:40 + โ”ƒ Lif โ•˜โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•• + โ”ƒ e is goo d. โ”‚ + โ” โ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ•Œโ”ค + โ”ƒ But I'm better. โ”‚ + โ”–โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + + + Scenario: Override color selections with runtime overrides + Given we use the config "basic_encrypted.yaml" + And we use the password "test" if prompted + When we run "jrnl -1 --config-override colors.body blue" + Then the config in memory should contain "colors.body: blue" + + + Scenario: Apply multiple config overrides + Given we use the config "basic_encrypted.yaml" + And we use the password "test" if prompted + When we run "jrnl -1 --config-override colors.body green --config-override editor 'nano'" + Then the config in memory should contain + editor: nano + colors: + title: none + body: green + tags: none + date: none + + + Scenario: Override default journal + Given we use the config "basic_dayone.yaml" + And we use the password "test" if prompted + When we run "jrnl --config-override journals.default features/journals/simple.journal 20 Mar 2000: The rain in Spain comes from clouds" + Then we should get no error + And we should see the message "Entry added" + When we run "jrnl -3 --config-override journals.default features/journals/simple.journal" + Then the output should be + 2000-03-20 09:00 The rain in Spain comes from clouds + + 2013-06-09 15:39 My first entry. + | Everything is alright + + 2013-06-10 15:40 Life is good. + | But I'm better. + + + Scenario: Make an entry into an overridden journal + Given we use the config "basic_dayone.yaml" + And we use the password "test" if prompted + When we run "jrnl --config-override journals.temp features/journals/simple.journal temp Sep 06 1969: @say Ni" + Then we should get no error + And we should see the message "Entry added" + When we run "jrnl --config-override journals.temp features/journals/simple.journal temp -3" + Then the output should be + 1969-09-06 09:00 @say Ni + + 2013-06-09 15:39 My first entry. + | Everything is alright + + 2013-06-10 15:40 Life is good. + | But I'm better. 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/data/configs/multiple.yaml b/tests/data/configs/multiple.yaml index 1501b383..2bed98b0 100644 --- a/tests/data/configs/multiple.yaml +++ b/tests/data/configs/multiple.yaml @@ -12,6 +12,7 @@ journals: new_encrypted: encrypt: true journal: features/journals/new_encrypted.journal + โœจ: features/journals/simple.journal linewrap: 80 tagsymbols: '@' timeformat: '%Y-%m-%d %H:%M' 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 b56c203f..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") @@ -84,6 +85,14 @@ def output_should_contain_version(cli_run, toml_version): assert toml_version in out, toml_version +@then(parse("the output should be {width:d} columns wide")) +def output_should_be_columns_wide(cli_run, width): + out = cli_run["stdout"] + out_lines = out.splitlines() + for line in out_lines: + assert len(line) <= width + + @then(parse('we should see the message "{text}"')) def should_see_the_message(text, cli_run): out = cli_run["stderr"] @@ -102,17 +111,18 @@ def should_see_the_message(text, cli_run): ) @then(parse('the config {should_or_should_not} contain "{some_yaml}"')) @then(parse("the config {should_or_should_not} contain\n{some_yaml}")) -def config_var(config_data, journal_name, should_or_should_not, some_yaml): +def config_var_on_disk(config_on_disk, journal_name, should_or_should_not, some_yaml): we_should = parse_should_or_should_not(should_or_should_not) - actual = config_data + actual = config_on_disk if journal_name: actual = actual["journals"][journal_name] - expected = yaml.load(some_yaml, Loader=yaml.FullLoader) + expected = yaml.load(some_yaml, Loader=yaml.SafeLoader) actual_slice = actual if type(actual) is dict: + # `expected` objects formatted in yaml only compare one level deep actual_slice = {key: actual.get(key, None) for key in expected.keys()} if we_should: @@ -121,6 +131,40 @@ def config_var(config_data, journal_name, should_or_should_not, some_yaml): assert expected != actual_slice +@then( + parse( + 'the config in memory for journal "{journal_name}" {should_or_should_not} contain "{some_yaml}"' + ) +) +@then( + parse( + 'the config in memory for journal "{journal_name}" {should_or_should_not} contain\n{some_yaml}' + ) +) +@then(parse('the config in memory {should_or_should_not} contain "{some_yaml}"')) +@then(parse("the config in memory {should_or_should_not} contain\n{some_yaml}")) +def config_var_in_memory( + config_in_memory, journal_name, should_or_should_not, some_yaml +): + we_should = parse_should_or_should_not(should_or_should_not) + + actual = config_in_memory["overrides"] + if journal_name: + actual = actual["journals"][journal_name] + + expected = yaml.load(some_yaml, Loader=yaml.SafeLoader) + + actual_slice = actual + if type(actual) is dict: + # `expected` objects formatted in yaml only compare one level deep + actual_slice = {key: get_nested_val(actual, key) for key in expected.keys()} + + if we_should: + assert expected == actual_slice + else: + assert expected != actual_slice + + @then("we should be prompted for a password") def password_was_called(cli_run): assert cli_run["mocks"]["getpass"].called @@ -137,15 +181,15 @@ def assert_dir_contains_files(file_list, cache_dir): @then(parse("the journal directory should contain\n{file_list}")) -def journal_directory_should_contain(config_data, file_list): - scoped_config = scope_config(config_data, "default") +def journal_directory_should_contain(config_on_disk, file_list): + scoped_config = scope_config(config_on_disk, "default") assert does_directory_contain_files(file_list, scoped_config["journal"]) @then(parse('journal "{journal_name}" should not exist')) -def journal_directory_should_not_exist(config_data, journal_name): - scoped_config = scope_config(config_data, journal_name) +def journal_directory_should_not_exist(config_on_disk, journal_name): + scoped_config = scope_config(config_on_disk, journal_name) assert not does_directory_contain_files( scoped_config["journal"], "." @@ -153,8 +197,8 @@ def journal_directory_should_not_exist(config_data, journal_name): @then(parse("the journal {should_or_should_not} exist")) -def journal_should_not_exist(config_data, should_or_should_not): - scoped_config = scope_config(config_data, "default") +def journal_should_not_exist(config_on_disk, should_or_should_not): + scoped_config = scope_config(config_on_disk, "default") expected_path = scoped_config["journal"] contains_files = does_directory_contain_files(expected_path, ".") @@ -301,15 +345,34 @@ def count_elements(number, item, cli_run): assert len(xml_tree.findall(".//" + item)) == number -@then(parse("the editor should have been called")) -@then(parse("the editor should have been called with {num_args} arguments")) -def count_editor_args(num_args, cli_run, editor_state): - assert cli_run["mocks"]["editor"].called +@then(parse("the editor {should_or_should_not} have been called")) +@then( + parse( + "the editor {should_or_should_not} have been called with {num_args} arguments" + ) +) +def count_editor_args(num_args, cli_run, editor_state, should_or_should_not): + we_should = parse_should_or_should_not(should_or_should_not) + + if we_should: + assert cli_run["mocks"]["editor"].called + else: + assert not cli_run["mocks"]["editor"].called if isinstance(num_args, int): assert len(editor_state["command"]) == int(num_args) +@then(parse("the stdin prompt {should_or_should_not} have been called")) +def stdin_prompt_called(cli_run, should_or_should_not): + we_should = parse_should_or_should_not(should_or_should_not) + + if we_should: + assert cli_run["mocks"]["stdin"].called + else: + assert not cli_run["mocks"]["stdin"].called + + @then(parse('the editor filename should end with "{suffix}"')) def editor_filename_suffix(suffix, editor_state): editor_filename = editor_state["tmpfile"]["name"] 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():