Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement category support #475

Merged
merged 26 commits into from
Jul 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
386f1d9
feat(categories): added basic category support
Jan 22, 2022
94f7c08
feat(categories): added to interactive layer
Jan 23, 2022
a1529da
feat(categories): allow for filtering by multiple categories and fixe…
Jan 24, 2022
0500cc5
chore: removed unnecessary db fields/code
Jan 24, 2022
44355a8
tests: all tests pass
Jan 24, 2022
512766e
tests(category): created tests
Jan 24, 2022
a9fb63d
docs: added category support
Jan 24, 2022
6a95923
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 24, 2022
20df442
fix: incompatible types
Jan 24, 2022
e712327
ci: fix E501 (line too long)
Jan 24, 2022
9e6c9fa
chore(ci): removed unnecesary lines to increase required code coverage
Jan 25, 2022
f80d93c
fix: can edit categories in interactive mode
Jan 25, 2022
3a0a699
chore: removed unneeded code for code coverage
Jan 25, 2022
f044096
test: category sql contraint
Jan 25, 2022
0738e0a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 25, 2022
16cb941
chore: removed unused method, added back drop_tables
Jan 25, 2022
004d812
test: category is deleted on todo deletion
Jan 31, 2022
b2063c8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 31, 2022
43d38cf
fix: add back stricter check
Jan 31, 2022
a20f595
style: remove unecessarily verbose method of concatting strings
0styx0 Jan 31, 2022
a7341c3
fix: revert to previous variable name
Jan 31, 2022
f81e26f
refactor: multiple selects -> left join
Jan 31, 2022
2825fbf
perf: use join instead of separate select statement
Feb 1, 2022
64834bb
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 1, 2022
118df55
style: fixed line length warning
Feb 1, 2022
c6af1d7
fix: added back stricter check
Feb 3, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Authors are listed in alphabetical order.
* Ben Moran <[email protected]>
* Benjamin Frank <[email protected]>
* Christian Geier <[email protected]>
* Christof Schulze <[email protected]>
* Doron Behar <[email protected]>
* Guilhem Saurel <[email protected]>
* Hugo Osvaldo Barrera <[email protected]>
Expand All @@ -28,6 +29,7 @@ Authors are listed in alphabetical order.
* Rimsha Khan <[email protected]>
* Sakshi Saraswat <[email protected]>
* Stephan Weller <[email protected]>
* Styx Meiseles <[email protected]>
* Swati Garg <[email protected]>
* Thomas Glanzmann <[email protected]>
* https://github.com/Pikrass
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ v4.1.0
* The "table" layout has been dropped in favour of a simpler, fluid layout. As
such, ``tabulate`` is not longer a required dependency.
* Added support for python 3.10.
* Added full support for categories.

v4.0.1
------
Expand Down
89 changes: 71 additions & 18 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from unittest import mock
from unittest.mock import call
from unittest.mock import patch
from uuid import uuid4

import click
import hypothesis.strategies as st
Expand All @@ -27,7 +28,7 @@ def test_list(tmpdir, runner, create):
assert not result.exception
assert not result.output.strip()

create("test.ics", "SUMMARY:harhar\n")
create("test.ics", f"UID:{uuid4()}\nSUMMARY:harhar\n")
result = runner.invoke(cli, ["list"])
assert not result.exception
assert "harhar" in result.output
Expand Down Expand Up @@ -57,14 +58,14 @@ def test_no_extra_whitespace(tmpdir, runner, create):
assert not result.exception
assert result.output == "\n"

create("test.ics", "SUMMARY:harhar\n")
create("test.ics", f"UID:{uuid4()}\nSUMMARY:harhar\n")
result = runner.invoke(cli, ["list"])
assert not result.exception
assert len(result.output.splitlines()) == 1


def test_percent(tmpdir, runner, create):
create("test.ics", "SUMMARY:harhar\nPERCENT-COMPLETE:78\n")
create("test.ics", f"UID:{uuid4()}\nSUMMARY:harhar\nPERCENT-COMPLETE:78\n")
result = runner.invoke(cli, ["list"])
assert not result.exception
assert "78%" in result.output
Expand Down Expand Up @@ -122,7 +123,9 @@ def test_list_inexistant(tmpdir, runner, create):


def test_show_existing(tmpdir, runner, create):
create("test.ics", "SUMMARY:harhar\nDESCRIPTION:Lots of text. Yum!\n")
create(
"test.ics", f"UID:{uuid4()}\nSUMMARY:harhar\nDESCRIPTION:Lots of text. Yum!\n"
)
result = runner.invoke(cli, ["list"])
result = runner.invoke(cli, ["show", "1"])
assert not result.exception
Expand All @@ -131,7 +134,7 @@ def test_show_existing(tmpdir, runner, create):


def test_show_inexistant(tmpdir, runner, create):
create("test.ics", "SUMMARY:harhar\n")
create("test.ics", f"UID:{uuid4()}\nSUMMARY:harhar\n")
result = runner.invoke(cli, ["list"])
result = runner.invoke(cli, ["show", "2"])
assert result.exit_code == 20
Expand Down Expand Up @@ -170,14 +173,14 @@ def test_two_events(tmpdir, runner):


def test_default_command(tmpdir, runner, create):
create("test.ics", "SUMMARY:harhar\n")
create("test.ics", f"UID:{uuid4()}\nSUMMARY:harhar\n")
result = runner.invoke(cli)
assert not result.exception
assert "harhar" in result.output


def test_delete(runner, create):
create("test.ics", "SUMMARY:harhar\n")
create("test.ics", f"UID:{uuid4()}\nSUMMARY:harhar\n")
result = runner.invoke(cli, ["list"])
assert not result.exception
result = runner.invoke(cli, ["delete", "1", "--yes"])
Expand All @@ -200,7 +203,7 @@ def test_delete_prompt(todo_factory, runner, todos):

def test_copy(tmpdir, runner, create):
tmpdir.mkdir("other_list")
create("test.ics", "SUMMARY:test_copy\n")
create("test.ics", f"UID:{uuid4()}\nSUMMARY:test_copy\n")
result = runner.invoke(cli, ["list"])
assert not result.exception
assert "test_copy" in result.output
Expand All @@ -217,7 +220,7 @@ def test_copy(tmpdir, runner, create):

def test_move(tmpdir, runner, create):
tmpdir.mkdir("other_list")
create("test.ics", "SUMMARY:test_move\n")
create("test.ics", f"UID:{uuid4()}\nSUMMARY:test_move\n")
result = runner.invoke(cli, ["list"])
assert not result.exception
assert "test_move" in result.output
Expand Down Expand Up @@ -344,8 +347,16 @@ def run_test(sort_key):


def test_sorting_output(tmpdir, runner, create):
create("test.ics", "SUMMARY:aaa\nDUE;VALUE=DATE-TIME;TZID=ART:20160102T000000\n")
create("test2.ics", "SUMMARY:bbb\nDUE;VALUE=DATE-TIME;TZID=ART:20160101T000000\n")
create(
"test.ics",
f"UID:{uuid4()}\nSUMMARY:aaa\n"
"DUE;VALUE=DATE-TIME;TZID=ART:20160102T000000\n",
)
create(
"test2.ics",
f"UID:{uuid4()}\nSUMMARY:bbb\n"
"DUE;VALUE=DATE-TIME;TZID=ART:20160101T000000\n",
)

examples = [("-summary", ["aaa", "bbb"]), ("due", ["aaa", "bbb"])]

Expand All @@ -371,8 +382,12 @@ def test_sorting_output(tmpdir, runner, create):


def test_sorting_null_values(tmpdir, runner, create):
create("test.ics", "SUMMARY:aaa\nPRIORITY:9\n")
create("test2.ics", "SUMMARY:bbb\nDUE;VALUE=DATE-TIME;TZID=ART:20160101T000000\n")
create("test.ics", f"UID:{uuid4()}\nSUMMARY:aaa\nPRIORITY:9\n")
create(
"test2.ics",
f"UID:{uuid4()}\nSUMMARY:bbb\n"
"DUE;VALUE=DATE-TIME;TZID=ART:20160101T000000\n",
)

result = runner.invoke(cli)
assert not result.exception
Expand Down Expand Up @@ -528,7 +543,7 @@ def test_empty_list(tmpdir, runner, create):


def test_show_location(tmpdir, runner, create):
create("test.ics", "SUMMARY:harhar\nLOCATION:Boston\n")
create("test.ics", f"UID:{uuid4()}\nSUMMARY:harhar\nLOCATION:Boston\n")

result = runner.invoke(cli, ["show", "1"])
assert "Boston" in result.output
Expand All @@ -551,11 +566,13 @@ def test_sort_mixed_timezones(runner, create):
"""
create(
"test.ics",
"SUMMARY:first\nDUE;VALUE=DATE-TIME;TZID=CET:20170304T180000\n", # 1700 UTC
f"UID:{uuid4()}\nSUMMARY:first\nDUE;"
"VALUE=DATE-TIME;TZID=CET:20170304T180000\n", # 1700 UTC
)
create(
"test2.ics",
"SUMMARY:second\nDUE;VALUE=DATE-TIME;TZID=HST:20170304T080000\n", # 1800 UTC
f"UID:{uuid4()}\nSUMMARY:second\nDUE;"
"VALUE=DATE-TIME;TZID=HST:20170304T080000\n", # 1800 UTC
)

result = runner.invoke(cli, ["list", "--status", "ANY"])
Expand Down Expand Up @@ -587,7 +604,9 @@ def test_due_bad_date(runner):


def test_multiple_todos_in_file(runner, create):
path = create("test.ics", "SUMMARY:a\nEND:VTODO\nBEGIN:VTODO\nSUMMARY:b\n")
path = create(
"test.ics", f"UID:{uuid4()}\nSUMMARY:a\nEND:VTODO\nBEGIN:VTODO\nSUMMARY:b\n"
)

for _ in range(2):
with patch("todoman.model.logger", spec=True) as mocked_logger:
Expand Down Expand Up @@ -845,6 +864,40 @@ def test_invoke_invalid_command(runner, tmpdir, config):
assert "Error: Invalid setting for [default_command]" in result.output


def test_new_categories_single(runner):
result = runner.invoke(cli, ["new", "-l", "default", "--category", "mine", "title"])

assert "[mine]" in result.output


def test_new_categories_multiple(runner):
result = runner.invoke(
cli, ["new", "-l", "default", "-c", "first", "-c", "second", "title"]
)

assert "[first, second]" in result.output


def test_list_categories_single(tmpdir, runner, create):
category = "fizzbuzz"
create("test.ics", f"UID:{uuid4()}\nSUMMARY:harhar\nCATEGORIES:{category}\n")
result = runner.invoke(cli, ["list", "--category", category])
assert not result.exception
assert category in result.output


def test_list_categories_multiple(tmpdir, runner, create):
category = ["git", "gud"]
create("test.ics", f"SUMMARY:harhar\nCATEGORIES:{category[0]}\n")
create("test1.ics", f"SUMMARY:harhar1\nCATEGORIES:{category[1]}\n")
result = runner.invoke(
cli, ["list", "--category", category[0], "--category", category[1]]
)
assert not result.exception
assert category[0] in result.output
assert category[1] in result.output


def test_show_priority(runner, todo_factory, todos):
todo_factory(summary="harhar\n", priority=1)

Expand Down Expand Up @@ -964,7 +1017,7 @@ def test_default_command_args(config, runner):
reverse=False,
lists=[],
location=None,
category=None,
categories=(),
grep=None,
start=None,
startable=None,
Expand Down
24 changes: 13 additions & 11 deletions tests/test_filtering.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from datetime import datetime
from datetime import timedelta
from uuid import uuid4

from todoman.cli import cli
from todoman.model import Database
Expand All @@ -11,10 +12,10 @@ def test_priority(tmpdir, runner, create):
assert not result.exception
assert not result.output.strip()

create("one.ics", "SUMMARY:haha\nPRIORITY:4\n")
create("two.ics", "SUMMARY:hoho\nPRIORITY:9\n")
create("three.ics", "SUMMARY:hehe\nPRIORITY:5\n")
create("four.ics", "SUMMARY:huhu\n")
create("one.ics", f"UID:{uuid4()}\nSUMMARY:haha\nPRIORITY:4\n")
create("two.ics", f"UID:{uuid4()}\nSUMMARY:hoho\nPRIORITY:9\n")
create("three.ics", f"UID:{uuid4()}\nSUMMARY:hehe\nPRIORITY:5\n")
create("four.ics", f"UID:{uuid4()}\nSUMMARY:huhu\n")

result_high = runner.invoke(cli, ["list", "--priority=high"])
assert not result_high.exception
Expand Down Expand Up @@ -53,9 +54,9 @@ def test_location(tmpdir, runner, create):
assert not result.exception
assert not result.output.strip()

create("one.ics", "SUMMARY:haha\nLOCATION: The Pool\n")
create("two.ics", "SUMMARY:hoho\nLOCATION: The Dungeon\n")
create("two.ics", "SUMMARY:harhar\n")
create("one.ics", f"UID:{uuid4()}\nSUMMARY:haha\nLOCATION: The Pool\n")
create("two.ics", f"UID:{uuid4()}\nSUMMARY:hoho\nLOCATION: The Dungeon\n")
create("two.ics", f"UID:{uuid4()}\nSUMMARY:harhar\n")
result = runner.invoke(cli, ["list", "--location", "Pool"])
assert not result.exception
assert "haha" in result.output
Expand All @@ -68,9 +69,9 @@ def test_category(tmpdir, runner, create):
assert not result.exception
assert not result.output.strip()

create("one.ics", "SUMMARY:haha\nCATEGORIES:work,trip\n")
create("one.ics", f"UID:{uuid4()}\nSUMMARY:haha\nCATEGORIES:work,trip\n")
create("two.ics", "CATEGORIES:trip\nSUMMARY:hoho\n")
create("three.ics", "SUMMARY:harhar\n")
create("three.ics", f"UID:{uuid4()}\nSUMMARY:harhar\n")
result = runner.invoke(cli, ["list", "--category", "work"])
assert not result.exception
assert "haha" in result.output
Expand Down Expand Up @@ -103,7 +104,7 @@ def test_grep(tmpdir, runner, create):
"five.ics",
"SUMMARY:research\nDESCRIPTION: Cure cancer\n",
)
create("six.ics", "SUMMARY:hoho\n")
create("six.ics", f"UID:{uuid4()}\nSUMMARY:hoho\n")
result = runner.invoke(cli, ["list", "--grep", "fun"])
assert not result.exception
assert "fun" in result.output
Expand Down Expand Up @@ -180,7 +181,8 @@ def test_due_naive(tmpdir, runner, create):
due = now + timedelta(hours=i)
create(
f"test_{i}.ics",
"SUMMARY:{}\nDUE;VALUE=DATE-TIME:{}\n".format(
"UID:{}\nSUMMARY:{}\nDUE;VALUE=DATE-TIME:{}\n".format(
uuid4(),
i,
due.strftime("%Y%m%dT%H%M%S"),
),
Expand Down
Loading