From 2890e33cac1acf9d86013b6d0627424d0ea88926 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Thu, 14 Nov 2019 12:00:23 +0100 Subject: [PATCH 01/27] Exit jrnl if no text entered into editor Fix #589 --- jrnl/cli.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jrnl/cli.py b/jrnl/cli.py index 65a535169..192e32333 100644 --- a/jrnl/cli.py +++ b/jrnl/cli.py @@ -200,6 +200,8 @@ def run(manual_args=None): util.prompt("[Could not read template at '']".format(config['template'])) sys.exit(1) raw = util.get_text_from_editor(config, template) + if not raw: + sys.exit() else: try: raw = util.py23_read("[Compose Entry; " + _exit_multiline_code + " to finish writing]\n") From 7a90f4076d0b55c290884e468f46430a3bcba99a Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Fri, 15 Nov 2019 09:27:01 +0100 Subject: [PATCH 02/27] Add test for aborting jrnl entry from editor --- features/core.feature | 5 +++++ features/data/configs/editor.yaml | 12 ++++++++++++ features/steps/core.py | 13 +++++++++++++ poetry.lock | 14 +++++++++++++- pyproject.toml | 1 + 5 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 features/data/configs/editor.yaml diff --git a/features/core.feature b/features/core.feature index ab86da423..95ec9351d 100644 --- a/features/core.feature +++ b/features/core.feature @@ -20,6 +20,11 @@ Feature: Basic reading and writing to a journal When we run "jrnl -n 1" Then the output should contain "2013-07-23 09:00 A cold and stormy day." + Scenario: Writing an empty entry from the editor + Given we use the config "editor.yaml" + When we open the editor and exit + Then the output should be empty + Scenario: Filtering for dates Given we use the config "basic.yaml" When we run "jrnl -on 2013-06-10 --short" diff --git a/features/data/configs/editor.yaml b/features/data/configs/editor.yaml new file mode 100644 index 000000000..8a06f9165 --- /dev/null +++ b/features/data/configs/editor.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "vim" +encrypt: false +highlight: true +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/features/steps/core.py b/features/steps/core.py index 83981d138..fead28558 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -6,6 +6,7 @@ from jrnl import __version__ from dateutil import parser as date_parser from collections import defaultdict +import mock import os import json import yaml @@ -27,6 +28,7 @@ def get_password(self, servicename, username): def delete_password(self, servicename, username, password): self.keys[servicename][username] = None + # set the keyring for keyring lib keyring.set_keyring(TestKeyring()) @@ -73,6 +75,12 @@ def set_config(context, config_file): cf.write("version: {}".format(__version__)) +@when('we open the editor and exit') +@mock.patch('jrnl.util.get_text_from_editor', return_value="") +def open_editor_and_exit_without_entering_text(context, dead_param_to_satisfy_behave): + run(context, "jrnl") + + @when('we run "{command}" and enter') @when('we run "{command}" and enter "{inputs}"') def run_with_input(context, command, inputs=None): @@ -166,6 +174,11 @@ def check_json_output_path(context, path, value): assert struct == value, struct +@then('the output should be empty') +def check_empty_output(context, text=None): + assert (text or context.text) is None + + @then('the output should be') @then('the output should be "{text}"') def check_output(context, text=None): diff --git a/poetry.lock b/poetry.lock index e772b2d26..d4c356423 100644 --- a/poetry.lock +++ b/poetry.lock @@ -220,6 +220,17 @@ click = ">=3.3" livereload = ">=2.5.1" tornado = ">=5.0" +[[package]] +category = "main" +description = "Rolling backport of unittest.mock for all Pythons" +name = "mock" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "3.0.5" + +[package.dependencies] +six = "*" + [[package]] category = "main" description = "NumPy is the fundamental package for array computing with Python." @@ -384,7 +395,7 @@ version = "1.5.1" pytz = "*" [metadata] -content-hash = "9896cf59c7552b6ad95219ee5555c7445a3fab39c2e4f4c6f3d991a36635e44b" +content-hash = "ab4bffce011d607d66bdb9a3cadc5b7c67870ef4682c765a55af4d75ea3e0f73" python-versions = "^3.7" [metadata.hashes] @@ -409,6 +420,7 @@ markdown = ["2e50876bcdd74517e7b71f3e7a76102050edec255b3983403f1a63e7c8a41e7a", markupsafe = ["00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", "09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", "09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", "1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", "24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", "29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", "43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", "46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", "500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", "535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", "62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", "6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", "717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", "79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", "7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", "88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", "8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", "98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", "9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", "9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", "ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", "b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", "b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", "b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", "ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", "c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", "cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", "e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"] mccabe = ["ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", "dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"] mkdocs = ["17d34329aad75d5de604b9ed4e31df3a4d235afefdc46ce7b1964fddb2e1e939", "8cc8b38325456b9e942c981a209eaeb1e9f3f77b493ad755bfef889b9c8d356a"] +mock = ["83657d894c90d5681d62155c82bda9c1187827525880eda8ff5df4ec813437c3", "d157e52d4e5b938c550f39eb2fd15610db062441a9c2747d3dbfa9298211d0f8"] numpy = ["0778076e764e146d3078b17c24c4d89e0ecd4ac5401beff8e1c87879043a0633", "141c7102f20abe6cf0d54c4ced8d565b86df4d3077ba2343b61a6db996cefec7", "14270a1ee8917d11e7753fb54fc7ffd1934f4d529235beec0b275e2ccf00333b", "27e11c7a8ec9d5838bc59f809bfa86efc8a4fd02e58960fa9c49d998e14332d5", "2a04dda79606f3d2f760384c38ccd3d5b9bb79d4c8126b67aff5eb09a253763e", "3c26010c1b51e1224a3ca6b8df807de6e95128b0908c7e34f190e7775455b0ca", "52c40f1a4262c896420c6ea1c6fda62cf67070e3947e3307f5562bd783a90336", "6e4f8d9e8aa79321657079b9ac03f3cf3fd067bf31c1cca4f56d49543f4356a5", "7242be12a58fec245ee9734e625964b97cf7e3f2f7d016603f9e56660ce479c7", "7dc253b542bfd4b4eb88d9dbae4ca079e7bf2e2afd819ee18891a43db66c60c7", "94f5bd885f67bbb25c82d80184abbf7ce4f6c3c3a41fbaa4182f034bba803e69", "a89e188daa119ffa0d03ce5123dee3f8ffd5115c896c2a9d4f0dbb3d8b95bfa3", "ad3399da9b0ca36e2f24de72f67ab2854a62e623274607e37e0ce5f5d5fa9166", "b0348be89275fd1d4c44ffa39530c41a21062f52299b1e3ee7d1c61f060044b8", "b5554368e4ede1856121b0dfa35ce71768102e4aa55e526cb8de7f374ff78722", "cbddc56b2502d3f87fda4f98d948eb5b11f36ff3902e17cb6cc44727f2200525", "d79f18f41751725c56eceab2a886f021d70fd70a6188fd386e29a045945ffc10", "dc2ca26a19ab32dc475dbad9dfe723d3a64c835f4c23f625c2b6566ca32b9f29", "dd9bcd4f294eb0633bb33d1a74febdd2b9018b8b8ed325f861fffcd2c7660bb8", "e8baab1bc7c9152715844f1faca6744f2416929de10d7639ed49555a85549f52", "ec31fe12668af687b99acf1567399632a7c47b0e17cfb9ae47c098644ef36797", "f12b4f7e2d8f9da3141564e6737d79016fe5336cc92de6814eba579744f65b0a", "f58ac38d5ca045a377b3b377c84df8175ab992c970a53332fa8ac2373df44ff7"] parse = ["1b68657434d371e5156048ca4a0c5aea5afc6ca59a2fea4dd1a575354f617142"] parse-type = ["6e906a66f340252e4c324914a60d417d33a4bea01292ea9bbf68b4fc123be8c9", "f596bdc75d3dd93036fbfe3d04127da9f6df0c26c36e01e76da85adef4336b3c"] diff --git a/pyproject.toml b/pyproject.toml index 1b84acde0..19eafee46 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,7 @@ asteval = "^0.9.14" colorama = {version = "^0.4.1",platform = "win32"} python-dateutil = "^2.8" pyyaml = "^5.1" +mock = "^3.0" [tool.poetry.dev-dependencies] behave = "^1.2" From f0e5fe965371ecce4108a71fb6b15a4f3cfd7547 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Fri, 15 Nov 2019 09:33:47 +0100 Subject: [PATCH 03/27] Use native mocking --- features/steps/core.py | 8 ++++---- poetry.lock | 14 +------------- pyproject.toml | 1 - 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/features/steps/core.py b/features/steps/core.py index fead28558..7070e10ee 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -1,12 +1,12 @@ from __future__ import unicode_literals from __future__ import absolute_import +from unittest.mock import patch from behave import given, when, then from jrnl import cli, install, Journal, util, plugins from jrnl import __version__ from dateutil import parser as date_parser from collections import defaultdict -import mock import os import json import yaml @@ -76,9 +76,9 @@ def set_config(context, config_file): @when('we open the editor and exit') -@mock.patch('jrnl.util.get_text_from_editor', return_value="") -def open_editor_and_exit_without_entering_text(context, dead_param_to_satisfy_behave): - run(context, "jrnl") +def open_editor_and_exit_without_entering_text(context): + with patch('jrnl.util.get_text_from_editor', return_value=""): + run(context, "jrnl") @when('we run "{command}" and enter') diff --git a/poetry.lock b/poetry.lock index d4c356423..e772b2d26 100644 --- a/poetry.lock +++ b/poetry.lock @@ -220,17 +220,6 @@ click = ">=3.3" livereload = ">=2.5.1" tornado = ">=5.0" -[[package]] -category = "main" -description = "Rolling backport of unittest.mock for all Pythons" -name = "mock" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "3.0.5" - -[package.dependencies] -six = "*" - [[package]] category = "main" description = "NumPy is the fundamental package for array computing with Python." @@ -395,7 +384,7 @@ version = "1.5.1" pytz = "*" [metadata] -content-hash = "ab4bffce011d607d66bdb9a3cadc5b7c67870ef4682c765a55af4d75ea3e0f73" +content-hash = "9896cf59c7552b6ad95219ee5555c7445a3fab39c2e4f4c6f3d991a36635e44b" python-versions = "^3.7" [metadata.hashes] @@ -420,7 +409,6 @@ markdown = ["2e50876bcdd74517e7b71f3e7a76102050edec255b3983403f1a63e7c8a41e7a", markupsafe = ["00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", "09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", "09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", "1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", "24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", "29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", "43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", "46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", "500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", "535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", "62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", "6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", "717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", "79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", "7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", "88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", "8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", "98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", "9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", "9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", "ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", "b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", "b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", "b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", "ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", "c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", "cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", "e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"] mccabe = ["ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", "dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"] mkdocs = ["17d34329aad75d5de604b9ed4e31df3a4d235afefdc46ce7b1964fddb2e1e939", "8cc8b38325456b9e942c981a209eaeb1e9f3f77b493ad755bfef889b9c8d356a"] -mock = ["83657d894c90d5681d62155c82bda9c1187827525880eda8ff5df4ec813437c3", "d157e52d4e5b938c550f39eb2fd15610db062441a9c2747d3dbfa9298211d0f8"] numpy = ["0778076e764e146d3078b17c24c4d89e0ecd4ac5401beff8e1c87879043a0633", "141c7102f20abe6cf0d54c4ced8d565b86df4d3077ba2343b61a6db996cefec7", "14270a1ee8917d11e7753fb54fc7ffd1934f4d529235beec0b275e2ccf00333b", "27e11c7a8ec9d5838bc59f809bfa86efc8a4fd02e58960fa9c49d998e14332d5", "2a04dda79606f3d2f760384c38ccd3d5b9bb79d4c8126b67aff5eb09a253763e", "3c26010c1b51e1224a3ca6b8df807de6e95128b0908c7e34f190e7775455b0ca", "52c40f1a4262c896420c6ea1c6fda62cf67070e3947e3307f5562bd783a90336", "6e4f8d9e8aa79321657079b9ac03f3cf3fd067bf31c1cca4f56d49543f4356a5", "7242be12a58fec245ee9734e625964b97cf7e3f2f7d016603f9e56660ce479c7", "7dc253b542bfd4b4eb88d9dbae4ca079e7bf2e2afd819ee18891a43db66c60c7", "94f5bd885f67bbb25c82d80184abbf7ce4f6c3c3a41fbaa4182f034bba803e69", "a89e188daa119ffa0d03ce5123dee3f8ffd5115c896c2a9d4f0dbb3d8b95bfa3", "ad3399da9b0ca36e2f24de72f67ab2854a62e623274607e37e0ce5f5d5fa9166", "b0348be89275fd1d4c44ffa39530c41a21062f52299b1e3ee7d1c61f060044b8", "b5554368e4ede1856121b0dfa35ce71768102e4aa55e526cb8de7f374ff78722", "cbddc56b2502d3f87fda4f98d948eb5b11f36ff3902e17cb6cc44727f2200525", "d79f18f41751725c56eceab2a886f021d70fd70a6188fd386e29a045945ffc10", "dc2ca26a19ab32dc475dbad9dfe723d3a64c835f4c23f625c2b6566ca32b9f29", "dd9bcd4f294eb0633bb33d1a74febdd2b9018b8b8ed325f861fffcd2c7660bb8", "e8baab1bc7c9152715844f1faca6744f2416929de10d7639ed49555a85549f52", "ec31fe12668af687b99acf1567399632a7c47b0e17cfb9ae47c098644ef36797", "f12b4f7e2d8f9da3141564e6737d79016fe5336cc92de6814eba579744f65b0a", "f58ac38d5ca045a377b3b377c84df8175ab992c970a53332fa8ac2373df44ff7"] parse = ["1b68657434d371e5156048ca4a0c5aea5afc6ca59a2fea4dd1a575354f617142"] parse-type = ["6e906a66f340252e4c324914a60d417d33a4bea01292ea9bbf68b4fc123be8c9", "f596bdc75d3dd93036fbfe3d04127da9f6df0c26c36e01e76da85adef4336b3c"] diff --git a/pyproject.toml b/pyproject.toml index 19eafee46..1b84acde0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,6 @@ asteval = "^0.9.14" colorama = {version = "^0.4.1",platform = "win32"} python-dateutil = "^2.8" pyyaml = "^5.1" -mock = "^3.0" [tool.poetry.dev-dependencies] behave = "^1.2" From d378e2522df11eb485265776cefad2d4b89c36cd Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Fri, 15 Nov 2019 09:38:09 +0100 Subject: [PATCH 04/27] Add comment explaining discrepancy between expected and asserted output --- features/core.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/features/core.feature b/features/core.feature index 95ec9351d..2f62c19b4 100644 --- a/features/core.feature +++ b/features/core.feature @@ -20,6 +20,7 @@ Feature: Basic reading and writing to a journal When we run "jrnl -n 1" Then the output should contain "2013-07-23 09:00 A cold and stormy day." + # Note that the expected output is actually "[Nothing saved to file]" but due to mocking limitations, we expect no output here. Scenario: Writing an empty entry from the editor Given we use the config "editor.yaml" When we open the editor and exit From c0a1c171f140df0b35c38cff232ce8b91e4fc7d1 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 16 Nov 2019 13:06:04 +0100 Subject: [PATCH 05/27] Fix check_empty_output method --- features/steps/core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/steps/core.py b/features/steps/core.py index ef3532d68..8bc73313e 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -190,8 +190,8 @@ def check_json_output_path(context, path, value): @then('the output should be empty') -def check_empty_output(context, text=None): - assert (text or context.text) is None +def check_empty_output(context): + assert context.stdout_capture is None @then('the output should be') From ccb55392dd6dc7d539adbbd7142429965e694e35 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 16 Nov 2019 13:18:14 +0100 Subject: [PATCH 06/27] Check message on stderr and patch subprocess.call --- features/core.feature | 4 ++-- features/steps/core.py | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/features/core.feature b/features/core.feature index 2f62c19b4..854fa53ff 100644 --- a/features/core.feature +++ b/features/core.feature @@ -23,8 +23,8 @@ Feature: Basic reading and writing to a journal # Note that the expected output is actually "[Nothing saved to file]" but due to mocking limitations, we expect no output here. Scenario: Writing an empty entry from the editor Given we use the config "editor.yaml" - When we open the editor and exit - Then the output should be empty + When we open the editor and enter "" + Then we should see the message "[Nothing saved to file]" Scenario: Filtering for dates Given we use the config "basic.yaml" diff --git a/features/steps/core.py b/features/steps/core.py index 8bc73313e..d4bf1b47e 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -67,9 +67,11 @@ def set_config(context, config_file): cf.write("version: {}".format(__version__)) -@when('we open the editor and exit') -def open_editor_and_exit_without_entering_text(context): - with patch('jrnl.util.get_text_from_editor', return_value=""): +@when('we open the editor and enter') +@when('we open the editor and enter {text}') +def open_editor_and_enter(context, text=""): + text = (text or context.text) + with patch('subprocess.call', return_value=text): run(context, "jrnl") From 9b0ebb7d847535603f0e631154e79391cd6d847f Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 16 Nov 2019 13:42:30 +0100 Subject: [PATCH 07/27] Add _mock_editor_function --- features/steps/core.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/features/steps/core.py b/features/steps/core.py index d4bf1b47e..66fa1e11d 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -71,7 +71,15 @@ def set_config(context, config_file): @when('we open the editor and enter {text}') def open_editor_and_enter(context, text=""): text = (text or context.text) - with patch('subprocess.call', return_value=text): + print("open_editor_and_enter called") + def _mock_editor_function(command): + print("_mock_editor_function called") + tmpfile = command.split()[-1] + print("TMPFILE:", tmpfile) + with open(tmpfile, "w+") as f: + f.write(text) + + with patch('subprocess.call', side_effect=_mock_editor_function): run(context, "jrnl") From 68772d3afe948137a11e5534c70bd68e739e0dee Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 16 Nov 2019 13:51:55 +0100 Subject: [PATCH 08/27] Update features/steps/core.py Co-Authored-By: pspeter --- features/steps/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/steps/core.py b/features/steps/core.py index 66fa1e11d..7ab7d20d8 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -74,7 +74,7 @@ def open_editor_and_enter(context, text=""): print("open_editor_and_enter called") def _mock_editor_function(command): print("_mock_editor_function called") - tmpfile = command.split()[-1] + tmpfile = command[-1] print("TMPFILE:", tmpfile) with open(tmpfile, "w+") as f: f.write(text) From e63ae25433dcd6dfc92569333fd2a85fde0ddb59 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 16 Nov 2019 14:07:39 +0100 Subject: [PATCH 09/27] Add return from mock function --- features/steps/core.py | 1 + 1 file changed, 1 insertion(+) diff --git a/features/steps/core.py b/features/steps/core.py index 7ab7d20d8..354bb2bbe 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -78,6 +78,7 @@ def _mock_editor_function(command): print("TMPFILE:", tmpfile) with open(tmpfile, "w+") as f: f.write(text) + return tmpfile with patch('subprocess.call', side_effect=_mock_editor_function): run(context, "jrnl") From 7dcc91431e947943be9d8a4b1415968ca77c5852 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 16 Nov 2019 14:16:36 +0100 Subject: [PATCH 10/27] Add debug statements --- features/steps/core.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/features/steps/core.py b/features/steps/core.py index 354bb2bbe..84d4ccc97 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -78,6 +78,8 @@ def _mock_editor_function(command): print("TMPFILE:", tmpfile) with open(tmpfile, "w+") as f: f.write(text) + + print("File contents:", open(tmpfile, "r").read()) return tmpfile with patch('subprocess.call', side_effect=_mock_editor_function): From 87571fa55f5533af92a11bfd21bf936c849563ee Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 16 Nov 2019 14:31:05 +0100 Subject: [PATCH 11/27] Debug --- jrnl/util.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jrnl/util.py b/jrnl/util.py index 959d63a17..3b35c366f 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -118,6 +118,8 @@ def get_text_from_editor(config, template=""): os.remove(tmpfile) if not raw: print('[Nothing saved to file]', file=sys.stderr) + else: + print("RAW: '" + raw + "'") return raw From 8d22283b93393316f8d293402e485c77b898d335 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 16 Nov 2019 14:35:50 +0100 Subject: [PATCH 12/27] Update features/steps/core.py Co-Authored-By: pspeter --- features/steps/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/steps/core.py b/features/steps/core.py index 84d4ccc97..2175bd287 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -68,7 +68,7 @@ def set_config(context, config_file): @when('we open the editor and enter') -@when('we open the editor and enter {text}') +@when('we open the editor and enter "{text}"') def open_editor_and_enter(context, text=""): text = (text or context.text) print("open_editor_and_enter called") From 4cfff00d0a3f1b7e7458f72815be5128f0d18999 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 16 Nov 2019 14:40:31 +0100 Subject: [PATCH 13/27] Move sys.exit() down --- jrnl/cli.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/jrnl/cli.py b/jrnl/cli.py index 3ba6ec94f..32cde8dc3 100644 --- a/jrnl/cli.py +++ b/jrnl/cli.py @@ -196,8 +196,6 @@ def run(manual_args=None): print(f"[Could not read template at '{config['template']}']", file=sys.stderr) sys.exit(1) raw = util.get_text_from_editor(config, template) - if not raw: - sys.exit() else: try: print("[Compose Entry; " + _exit_multiline_code + " to finish writing]\n", file=sys.stderr) @@ -208,7 +206,7 @@ def run(manual_args=None): if raw: args.text = [raw] else: - mode_compose = False + sys.exit() # This is where we finally open the journal! try: From c23efa7f801550c808e1adb4ec654bc11be70305 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 16 Nov 2019 14:42:39 +0100 Subject: [PATCH 14/27] Fix test? --- features/core.feature | 2 +- features/steps/core.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/core.feature b/features/core.feature index 854fa53ff..bff53e2ff 100644 --- a/features/core.feature +++ b/features/core.feature @@ -23,7 +23,7 @@ Feature: Basic reading and writing to a journal # Note that the expected output is actually "[Nothing saved to file]" but due to mocking limitations, we expect no output here. Scenario: Writing an empty entry from the editor Given we use the config "editor.yaml" - When we open the editor and enter "" + When we open the editor and enter nothing Then we should see the message "[Nothing saved to file]" Scenario: Filtering for dates diff --git a/features/steps/core.py b/features/steps/core.py index 2175bd287..95e39af89 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -67,7 +67,7 @@ def set_config(context, config_file): cf.write("version: {}".format(__version__)) -@when('we open the editor and enter') +@when('we open the editor and enter nothing') @when('we open the editor and enter "{text}"') def open_editor_and_enter(context, text=""): text = (text or context.text) From bca12b4b16a6f0586b24f0cd3f53c9636fa1213a Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 16 Nov 2019 14:46:34 +0100 Subject: [PATCH 15/27] Fix test? --- features/steps/core.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/features/steps/core.py b/features/steps/core.py index 95e39af89..58d50e85f 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -67,7 +67,7 @@ def set_config(context, config_file): cf.write("version: {}".format(__version__)) -@when('we open the editor and enter nothing') +@when('we open the editor and enter ""') @when('we open the editor and enter "{text}"') def open_editor_and_enter(context, text=""): text = (text or context.text) @@ -77,7 +77,10 @@ def _mock_editor_function(command): tmpfile = command[-1] print("TMPFILE:", tmpfile) with open(tmpfile, "w+") as f: - f.write(text) + if text is not None: + f.write(text) + else: + f.write("") print("File contents:", open(tmpfile, "r").read()) return tmpfile From 5d75bc25c7297a086b81ac8b0963b0289ab9b0b0 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 16 Nov 2019 14:49:07 +0100 Subject: [PATCH 16/27] Fix test? --- features/core.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index bff53e2ff..854fa53ff 100644 --- a/features/core.feature +++ b/features/core.feature @@ -23,7 +23,7 @@ Feature: Basic reading and writing to a journal # Note that the expected output is actually "[Nothing saved to file]" but due to mocking limitations, we expect no output here. Scenario: Writing an empty entry from the editor Given we use the config "editor.yaml" - When we open the editor and enter nothing + When we open the editor and enter "" Then we should see the message "[Nothing saved to file]" Scenario: Filtering for dates From b1c7deb9b9fc8694372126f5cfe0840c53448cb9 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 16 Nov 2019 14:52:19 +0100 Subject: [PATCH 17/27] Clean up debug statements --- features/steps/core.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/features/steps/core.py b/features/steps/core.py index 58d50e85f..b48562e7a 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -73,16 +73,13 @@ def open_editor_and_enter(context, text=""): text = (text or context.text) print("open_editor_and_enter called") def _mock_editor_function(command): - print("_mock_editor_function called") tmpfile = command[-1] - print("TMPFILE:", tmpfile) with open(tmpfile, "w+") as f: if text is not None: f.write(text) else: f.write("") - print("File contents:", open(tmpfile, "r").read()) return tmpfile with patch('subprocess.call', side_effect=_mock_editor_function): From 7b84935470cbbbb0436c84d03d69dd48a7643be9 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 16 Nov 2019 14:53:07 +0100 Subject: [PATCH 18/27] Clean up debug statements --- jrnl/util.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/jrnl/util.py b/jrnl/util.py index 3b35c366f..959d63a17 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -118,8 +118,6 @@ def get_text_from_editor(config, template=""): os.remove(tmpfile) if not raw: print('[Nothing saved to file]', file=sys.stderr) - else: - print("RAW: '" + raw + "'") return raw From 59a6aa3cfdf50cdc12c7e428926c6bf93d9b550f Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 16 Nov 2019 14:54:03 +0100 Subject: [PATCH 19/27] Remove extraneous code --- features/steps/core.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/features/steps/core.py b/features/steps/core.py index b48562e7a..847cbeaf2 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -202,11 +202,6 @@ def check_json_output_path(context, path, value): assert struct == value, struct -@then('the output should be empty') -def check_empty_output(context): - assert context.stdout_capture is None - - @then('the output should be') @then('the output should be "{text}"') def check_output(context, text=None): From 91dcb812d753dc07e12c24f23c64d5b3215c31a2 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sun, 17 Nov 2019 01:49:07 +0100 Subject: [PATCH 20/27] Remove extra space --- jrnl/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jrnl/cli.py b/jrnl/cli.py index 32cde8dc3..738087e44 100644 --- a/jrnl/cli.py +++ b/jrnl/cli.py @@ -176,7 +176,7 @@ def run(manual_args=None): log.debug('Using journal "%s"', journal_name) mode_compose, mode_export, mode_import = guess_mode(args, config) - + # How to quit writing? if "win32" in sys.platform: _exit_multiline_code = "on a blank line, press Ctrl+Z and then Enter" From 455261c55e125433daa32e7c8e259ad7bb810683 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sun, 17 Nov 2019 01:49:46 +0100 Subject: [PATCH 21/27] Add test for empty stdin input --- features/core.feature | 10 +++++++++- features/steps/core.py | 9 +++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index 854fa53ff..598b99f81 100644 --- a/features/core.feature +++ b/features/core.feature @@ -20,12 +20,20 @@ Feature: Basic reading and writing to a journal When we run "jrnl -n 1" Then the output should contain "2013-07-23 09:00 A cold and stormy day." - # Note that the expected output is actually "[Nothing saved to file]" but due to mocking limitations, we expect no output here. Scenario: Writing an empty entry from the editor Given we use the config "editor.yaml" When we open the editor and enter "" Then we should see the message "[Nothing saved to file]" + Scenario: Writing an empty entry from the command line + Given we use the config "basic.yaml" + When we run "jrnl ''" + Then we should get no error + And the unstripped output should be + """ + + """ + Scenario: Filtering for dates Given we use the config "basic.yaml" When we run "jrnl -on 2013-06-10 --short" diff --git a/features/steps/core.py b/features/steps/core.py index 847cbeaf2..40b44f92a 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -211,6 +211,15 @@ def check_output(context, text=None): for line_text, line_out in zip(text, out): assert line_text.strip() == line_out.strip(), [line_text.strip(), line_out.strip()] +@then('the unstripped output should be') +@then('the unstripped output should be "{text}"') +def check_output(context, text=None): + text = (text or context.text).splitlines() + out = context.stdout_capture.getvalue().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 == line_out, [line_text, line_out] + @then('the output should contain "{text}" in the local time') def check_output_time_inline(context, text): From fce60a364fdd16b17c404400b383282444a62d91 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sun, 17 Nov 2019 01:49:58 +0100 Subject: [PATCH 22/27] Remove extra debug line --- features/steps/core.py | 1 - 1 file changed, 1 deletion(-) diff --git a/features/steps/core.py b/features/steps/core.py index 40b44f92a..b9d6c02ce 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -71,7 +71,6 @@ def set_config(context, config_file): @when('we open the editor and enter "{text}"') def open_editor_and_enter(context, text=""): text = (text or context.text) - print("open_editor_and_enter called") def _mock_editor_function(command): tmpfile = command[-1] with open(tmpfile, "w+") as f: From 0aee900ffc66437061fc873f003ea96a3c720e58 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sun, 17 Nov 2019 01:54:49 +0100 Subject: [PATCH 23/27] Fix test? --- features/core.feature | 3 +-- features/steps/core.py | 9 --------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/features/core.feature b/features/core.feature index 598b99f81..23058e124 100644 --- a/features/core.feature +++ b/features/core.feature @@ -29,9 +29,8 @@ Feature: Basic reading and writing to a journal Given we use the config "basic.yaml" When we run "jrnl ''" Then we should get no error - And the unstripped output should be + And the output should be """ - """ Scenario: Filtering for dates diff --git a/features/steps/core.py b/features/steps/core.py index b9d6c02ce..2ec9e4163 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -210,15 +210,6 @@ def check_output(context, text=None): for line_text, line_out in zip(text, out): assert line_text.strip() == line_out.strip(), [line_text.strip(), line_out.strip()] -@then('the unstripped output should be') -@then('the unstripped output should be "{text}"') -def check_output(context, text=None): - text = (text or context.text).splitlines() - out = context.stdout_capture.getvalue().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 == line_out, [line_text, line_out] - @then('the output should contain "{text}" in the local time') def check_output_time_inline(context, text): From b793ce5d6c25ae604cbb1762dbdc5bbb23777007 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sun, 17 Nov 2019 01:57:19 +0100 Subject: [PATCH 24/27] Fix test? --- features/core.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/features/core.feature b/features/core.feature index 23058e124..f37e151bc 100644 --- a/features/core.feature +++ b/features/core.feature @@ -31,6 +31,7 @@ Feature: Basic reading and writing to a journal Then we should get no error And the output should be """ + """ Scenario: Filtering for dates From e4012426ca8f3750a14d7c0bbf3159b61f28f6a2 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sun, 17 Nov 2019 02:07:06 +0100 Subject: [PATCH 25/27] Update features/core.feature Co-Authored-By: pspeter --- features/core.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index f37e151bc..50f409847 100644 --- a/features/core.feature +++ b/features/core.feature @@ -27,7 +27,7 @@ Feature: Basic reading and writing to a journal Scenario: Writing an empty entry from the command line Given we use the config "basic.yaml" - When we run "jrnl ''" + When we run "jrnl" and enter "" Then we should get no error And the output should be """ From 9701401946e6d75b953e580e782f7eb79e103253 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Mon, 18 Nov 2019 14:51:41 +0100 Subject: [PATCH 26/27] Fix test? --- features/steps/core.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/features/steps/core.py b/features/steps/core.py index 2ec9e4163..0e4e2a75a 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -101,12 +101,18 @@ def prompt_return(prompt=""): @when('we run "{command}" and enter') +@when('we run "{command}" and enter ""') @when('we run "{command}" and enter "{inputs1}"') @when('we run "{command}" and enter "{inputs1}" and "{inputs2}"') def run_with_input(context, command, inputs1="", inputs2=""): # 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()' - text = iter((inputs1, inputs2)) if inputs1 else iter(context.text.split("\n")) + if inputs1: + text = iter((inputs1, inputs2)) + elif context.text: + text = iter(context.text.split("\n")) + else: + text = "" args = ushlex(command)[1:] with patch("builtins.input", side_effect=_mock_input(text)) as mock_input: with patch("jrnl.util.getpass", side_effect=_mock_getpass(text)) as mock_getpass: From 7fbb5db5e71c14d47d94d966b681eb8b221f78df Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Mon, 18 Nov 2019 15:34:31 +0100 Subject: [PATCH 27/27] Fix no stdin input test --- features/core.feature | 3 +-- features/steps/core.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/features/core.feature b/features/core.feature index 50f409847..36601fdef 100644 --- a/features/core.feature +++ b/features/core.feature @@ -28,8 +28,7 @@ Feature: Basic reading and writing to a journal Scenario: Writing an empty entry from the command line Given we use the config "basic.yaml" When we run "jrnl" and enter "" - Then we should get no error - And the output should be + Then the output should be """ """ diff --git a/features/steps/core.py b/features/steps/core.py index 0e4e2a75a..af4d19a3d 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -112,7 +112,7 @@ def run_with_input(context, command, inputs1="", inputs2=""): elif context.text: text = iter(context.text.split("\n")) else: - text = "" + text = iter(("", "")) args = ushlex(command)[1:] with patch("builtins.input", side_effect=_mock_input(text)) as mock_input: with patch("jrnl.util.getpass", side_effect=_mock_getpass(text)) as mock_getpass: