Skip to content

Commit

Permalink
Add new -today-in-history, -month, -day, and -year search fil…
Browse files Browse the repository at this point in the history
…ters (#1145)

* Introduce -reminisce, -month, -day, and -year
* Update expected_args in parse_args tests
* Add check before creating compare_d
* Misc changes
* Implement testing for -month, -day, -year, and -reminisce
* Compress tests into one Scenario Outline
* Fix failing tests by updating dates_similar journal
* Create 'we set current date and time to' step
* Use time.parse in reminisce
* Update dates_similar journal
* Make 'Searching in a journal' test shorter
* Lint
* Implement reminiscing test
* Add combination tests
* Finalize tests
* Finalize pytests
* Simplify reminisce tests
* Change reminsice help (since it also shows today's entries)
* Re-do tests; use various tests
* Remove old test data
* Better scenario description
* Standardize format for compare_d
* Rename -reminisce to -today-in-history
  • Loading branch information
KarimPwnz committed Jan 16, 2021
1 parent 18058c7 commit f0e8fa2
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 0 deletions.
90 changes: 90 additions & 0 deletions features/search.feature
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,96 @@ Feature: Searching in a journal
| But I'm better.
"""

Scenario Outline: Searching by month
Given we use the config "<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 "<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 "<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 "<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 "<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'"
Expand Down
21 changes: 21 additions & 0 deletions features/steps/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import toml
import yaml

import jrnl.time
from jrnl import Journal
from jrnl import __version__
from jrnl import plugins
Expand Down Expand Up @@ -159,6 +160,11 @@ def disable_keyring(context):
keyring.core.set_keyring(NoKeyring())


@given('we set current date and time to "{dt}"')
def set_datetime(context, dt):
context.now = dt


@when('we change directory to "{path}"')
def move_up_dir(context, path):
os.chdir(path)
Expand Down Expand Up @@ -197,6 +203,7 @@ def _mock_editor(command):
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) \
:
Expand Down Expand Up @@ -289,6 +296,18 @@ def prompt_return(prompt=""):
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}"')
Expand Down Expand Up @@ -322,6 +341,7 @@ def _mock_editor(command):
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) \
:
Expand Down Expand Up @@ -406,6 +426,7 @@ def _mock_editor(command):
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) \
:
Expand Down
11 changes: 11 additions & 0 deletions jrnl/Journal.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ def tags(self):
def filter(
self,
tags=[],
month=None,
day=None,
year=None,
start_date=None,
end_date=None,
starred=False,
Expand Down Expand Up @@ -220,11 +223,19 @@ def filter(
if contains:
contains_lower = contains.casefold()

# Create datetime object for comparison below
# this approach allows various formats
if month or day or year:
compare_d = time.parse(f"{month or 1}.{day or 1}.{year or 1}")

result = [
entry
for entry in self.entries
if (not tags or tagged(entry.tags))
and (not starred or entry.starred)
and (not month or entry.date.month == compare_d.month)
and (not day or entry.date.day == compare_d.day)
and (not year or entry.date.year == compare_d.year)
and (not start_date or entry.date >= start_date)
and (not end_date or entry.date <= end_date)
and (not exclude or not excluded(entry.tags))
Expand Down
24 changes: 24 additions & 0 deletions jrnl/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,30 @@ def parse_args(args=[]):
reading.add_argument(
"-on", dest="on_date", metavar="DATE", help="Show entries on this date"
)
reading.add_argument(
"-today-in-history",
dest="today_in_history",
action="store_true",
help="Show entries of today over the years",
)
reading.add_argument(
"-month",
dest="month",
metavar="DATE",
help="Show entries on this month of any year",
)
reading.add_argument(
"-day",
dest="day",
metavar="DATE",
help="Show entries on this day of any month",
)
reading.add_argument(
"-year",
dest="year",
metavar="DATE",
help="Show entries of a specific year",
)
reading.add_argument(
"-from",
dest="start_date",
Expand Down
13 changes: 13 additions & 0 deletions jrnl/jrnl.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from .editor import get_text_from_editor
from .editor import get_text_from_stdin
from .exception import UserAbort
from . import time


def run(args):
Expand Down Expand Up @@ -77,6 +78,10 @@ def _is_write_mode(args, config, **kwargs):
args.edit,
args.export,
args.end_date,
args.today_in_history,
args.month,
args.day,
args.year,
args.limit,
args.on_date,
args.short,
Expand Down Expand Up @@ -206,8 +211,16 @@ def _search_journal(args, journal, **kwargs):
if args.on_date:
args.start_date = args.end_date = args.on_date

if args.today_in_history:
now = time.parse("now")
args.day = now.day
args.month = now.month

journal.filter(
tags=args.text,
month=args.month,
day=args.day,
year=args.year,
start_date=args.start_date,
end_date=args.end_date,
strict=args.strict,
Expand Down
25 changes: 25 additions & 0 deletions tests/test_parse_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ def expected_args(**kwargs):
"delete": False,
"edit": False,
"end_date": None,
"today_in_history": False,
"month": None,
"day": None,
"year": None,
"excluded": [],
"export": False,
"filename": None,
Expand Down Expand Up @@ -147,6 +151,27 @@ def test_on_date_alone():
assert cli_as_dict("-on 'saturday'") == expected_args(on_date="saturday")


def test_month_alone():
assert cli_as_dict("-month 1") == expected_args(month="1")
assert cli_as_dict("-month 01") == expected_args(month="01")
assert cli_as_dict("-month January") == expected_args(month="January")
assert cli_as_dict("-month Jan") == expected_args(month="Jan")


def test_day_alone():
assert cli_as_dict("-day 1") == expected_args(day="1")
assert cli_as_dict("-day 01") == expected_args(day="01")


def test_year_alone():
assert cli_as_dict("-year 2021") == expected_args(year="2021")
assert cli_as_dict("-year 21") == expected_args(year="21")


def test_today_in_history_alone():
assert cli_as_dict("-today-in-history") == expected_args(today_in_history=True)


def test_short_alone():
assert cli_as_dict("--short") == expected_args(short=True)

Expand Down

0 comments on commit f0e8fa2

Please sign in to comment.