From b0be9867594d29659e5998d68a931ba11ae5db8a Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 5 Sep 2020 15:26:39 -0700 Subject: [PATCH] add more tests, add more functionality to behave for calling mock editor --- features/config.feature | 11 +++ features/core.feature | 101 ---------------------------- features/dayone.feature | 21 ++++++ features/dayone_regressions.feature | 22 ------ features/import.feature | 65 ++++++++++++++++++ features/regression.feature | 8 --- features/steps/core.py | 69 +++++++++++++++---- features/tagging.feature | 3 +- features/writing.feature | 45 +++++++++++++ 9 files changed, 199 insertions(+), 146 deletions(-) create mode 100644 features/config.feature delete mode 100644 features/dayone_regressions.feature create mode 100644 features/import.feature create mode 100644 features/writing.feature diff --git a/features/config.feature b/features/config.feature new file mode 100644 index 00000000..bae84618 --- /dev/null +++ b/features/config.feature @@ -0,0 +1,11 @@ +Feature: Reading & writing the config file + + Scenario: Sending an argument with spaces to the editor should work + Given we use the config "editor-args.yaml" + When we open the editor and enter "lorem ipsum" + Then the editor should have been called with 5 arguments + And one editor argument should be "vim" + And one editor argument should be "-f" + And one editor argument should be "-c" + And one editor argument should match "'?setf markdown'?" + diff --git a/features/core.feature b/features/core.feature index bf103f17..1cb8aa95 100644 --- a/features/core.feature +++ b/features/core.feature @@ -26,44 +26,6 @@ Feature: Basic reading and writing to a journal | There is a blank line above this. """ - Scenario: Multiline entry with punctuation - Given we use the config "basic.yaml" - 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" - - Scenario: Single line entry with punctuation - Given we use the config "basic.yaml" - When we run "jrnl This is. the title" - And we run "jrnl -n 1" - Then the output should contain "| the title" - - Scenario: Writing an entry from command line - Given we use the config "basic.yaml" - 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." - - Scenario: Writing an empty entry from the editor - Given we use the config "editor.yaml" - When we open the editor and enter nothing - Then we should see the message "[Nothing saved to file]" - - Scenario: Sending an argument with spaces to the editor should work - Given we use the config "editor-args.yaml" - When we open the editor and enter "lorem ipsum" - Then the editor should have been called with 5 arguments - And one editor argument should be "vim" - And one editor argument should be "-f" - And one editor argument should be "-c" - And one editor argument should match "'?setf markdown'?" - - Scenario: Writing an empty entry from the command line - Given we use the config "basic.yaml" - When we run "jrnl" and enter nothing - 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" @@ -133,66 +95,3 @@ Feature: Basic reading and writing to a journal Then the output should contain "jrnl" And the output should contain "Python" - Scenario: --import allows new entry from stdin - Given we use the config "basic.yaml" - When we run "jrnl --import" and pipe "[2020-07-05 15:00] Observe and import." - And we run "jrnl -1" - Then the journal should contain "[2020-07-05 15:00] Observe and import." - And the output should contain "Observe and import" - - Scenario: --import allows new large entry from stdin - Given we use the config "basic.yaml" - 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. - """ - And we run "jrnl -1" - Then the journal should contain "[2020-07-05 15:00] Observe and import." - And the output should contain "Observe and import" - And the output should contain "Lorem ipsum" - And the output should contain "end of entry." - - Scenario: --import allows multiple new entries from stdin - Given we use the config "basic.yaml" - 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 the journal should contain "[2020-07-05 15:00] Observe and import." - Then the journal should contain "[2020-07-05 15:01] Twice as nice." - - Scenario: --import allows import new entries from file - Given we use the config "basic.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 doesn't get confused with piping and file - Given we use the config "basic.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/dayone.feature b/features/dayone.feature index 13f0e71b..4b69b0c9 100644 --- a/features/dayone.feature +++ b/features/dayone.feature @@ -69,3 +69,24 @@ Feature: Dayone specific implementation details. 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: 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!" + + # 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. + """ diff --git a/features/dayone_regressions.feature b/features/dayone_regressions.feature deleted file mode 100644 index 2ece3fbf..00000000 --- a/features/dayone_regressions.feature +++ /dev/null @@ -1,22 +0,0 @@ -Feature: Zapped Dayone bugs stay dead! - - # fails when system time is UTC (as on Travis-CI) - @skip - 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!" - - # 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. - """ diff --git a/features/import.feature b/features/import.feature new file mode 100644 index 00000000..f05ca98a --- /dev/null +++ b/features/import.feature @@ -0,0 +1,65 @@ +Feature: Importing data + + Scenario: --import allows new entry from stdin + Given we use the config "basic.yaml" + When we run "jrnl --import" and pipe "[2020-07-05 15:00] Observe and import." + And we run "jrnl -1" + Then the journal should contain "[2020-07-05 15:00] Observe and import." + And the output should contain "Observe and import" + + Scenario: --import allows new large entry from stdin + Given we use the config "basic.yaml" + 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. + """ + And we run "jrnl -1" + Then the journal should contain "[2020-07-05 15:00] Observe and import." + And the output should contain "Observe and import" + And the output should contain "Lorem ipsum" + And the output should contain "end of entry." + + Scenario: --import allows multiple new entries from stdin + Given we use the config "basic.yaml" + 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 the journal should contain "[2020-07-05 15:00] Observe and import." + Then the journal should contain "[2020-07-05 15:01] Twice as nice." + + Scenario: --import allows import new entries from file + Given we use the config "basic.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 "basic.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/regression.feature b/features/regression.feature index 9425280e..7dc32942 100644 --- a/features/regression.feature +++ b/features/regression.feature @@ -1,13 +1,5 @@ Feature: Zapped bugs should stay dead. - Scenario: Writing an entry does not print the entire journal - # https://github.com/jrnl-org/jrnl/issues/87 - Given we use the config "basic.yaml" - 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" - Scenario: Date with time should be parsed correctly # https://github.com/jrnl-org/jrnl/issues/117 Given we use the config "basic.yaml" diff --git a/features/steps/core.py b/features/steps/core.py index 8d1ea3e8..da25d831 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -122,7 +122,7 @@ def open_editor_and_enter(context, method, text=""): else: file_method = "r+" - def _mock_editor_function(command): + def _mock_editor(command): context.editor_command = command tmpfile = command[-1] with open(tmpfile, file_method) as f: @@ -133,16 +133,26 @@ def open_editor_and_enter(context, method, text=""): # fmt: off # see: https://github.com/psf/black/issues/664 with \ - patch("subprocess.call", side_effect=_mock_editor_function), \ + patch("subprocess.call", side_effect=_mock_editor) as mock_editor, \ patch("sys.stdin.isatty", return_value=True) \ : + context.editor = mock_editor cli(["--edit"]) # 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): - assert len(context.editor_command) == int(num) +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}"') @@ -192,12 +202,19 @@ def run_with_input(context, command, inputs=""): args = ushlex(command)[1:] + def _mock_editor(command): + context.editor_command = command + tmpfile = command[-1] + context.editor_file = tmpfile + Path(tmpfile).touch() + # 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(text)) as mock_getpass, \ - patch("sys.stdin.read", side_effect=text) as mock_read \ + patch("sys.stdin.read", side_effect=text) as mock_read, \ + patch("subprocess.call", side_effect=_mock_editor) as mock_editor \ : try: cli(args or []) @@ -205,17 +222,43 @@ def run_with_input(context, command, inputs=""): except SystemExit as e: context.exit_status = e.code - # at least one of the mocked input methods got called - assert mock_input.called or mock_getpass.called or mock_read.called - # all inputs were used - try: - next(text) - assert False, "Not all inputs were consumed" - except StopIteration: - pass + # 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 were prompted for a password") +def password_was_called(context, method): + assert 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}"') diff --git a/features/tagging.feature b/features/tagging.feature index 7a94418f..20ada178 100644 --- a/features/tagging.feature +++ b/features/tagging.feature @@ -78,13 +78,12 @@ Feature: Tagging And we run "jrnl today: I think this will show up @thought" And we run "jrnl today: This should @never show up @thought" And we run "jrnl today: What a nice day for filtering @thought" - And we run "jrnl --tags -not @not @never" + And we run "jrnl --tags -not @not -not @never" Then the output should be """ @thought : 2 """ - Scenario: Printing a journal that has multiline entries with tags Given we use the config "multiline-tags.yaml" When we run "jrnl -n 1" diff --git a/features/writing.feature b/features/writing.feature new file mode 100644 index 00000000..3638d9da --- /dev/null +++ b/features/writing.feature @@ -0,0 +1,45 @@ +Feature: Writing new entries. + + Scenario: Multiline entry with punctuation + Given we use the config "basic.yaml" + 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" + + Scenario: Single line entry with punctuation + Given we use the config "basic.yaml" + When we run "jrnl This is. the title" + And we run "jrnl -n 1" + Then the output should contain "| the title" + + Scenario: Writing an entry from command line + Given we use the config "basic.yaml" + 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." + + Scenario: Writing an empty entry from the editor + Given we use the config "editor.yaml" + When we open the editor and enter nothing + 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" and enter nothing + Then the output should be empty + And the editor should not have been called + + Scenario: Writing an empty entry from the editor + Given we use the config "editor.yaml" + When we run "jrnl" and enter nothing + Then the output should be empty + And the editor should have been called + + Scenario: Writing an entry does not print the entire journal + # https://github.com/jrnl-org/jrnl/issues/87 + Given we use the config "basic.yaml" + 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"