Skip to content

Commit 4c1c6a7

Browse files
author
Hugo
authored
Merge pull request #475 from 0styx0/implement_categories
feat: Implement category support
2 parents 2d33402 + c6af1d7 commit 4c1c6a7

10 files changed

Lines changed: 292 additions & 72 deletions

File tree

AUTHORS.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Authors are listed in alphabetical order.
1515
* Ben Moran <github@benmoran.net>
1616
* Benjamin Frank <ben+gitlab@pipsfrank.de>
1717
* Christian Geier <geier@lostpackets.de>
18+
* Christof Schulze <christof@christofschulze.com>
1819
* Doron Behar <me@doronbehar.com>
1920
* Guilhem Saurel <guilhem.saurel@gmail.com>
2021
* Hugo Osvaldo Barrera <hugo@barrera.io>
@@ -28,6 +29,7 @@ Authors are listed in alphabetical order.
2829
* Rimsha Khan <rimshakhan.rk03@gmail.com>
2930
* Sakshi Saraswat <saraswatsakshi.121@gmail.com>
3031
* Stephan Weller <stephan.weller@web.de>
32+
* Styx Meiseles <opensource@0styx0.xyz>
3133
* Swati Garg <swati4star@gmail.com>
3234
* Thomas Glanzmann <thomas@glanzmann.de>
3335
* https://github.com/Pikrass

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ v4.1.0
1010
* The "table" layout has been dropped in favour of a simpler, fluid layout. As
1111
such, ``tabulate`` is not longer a required dependency.
1212
* Added support for python 3.10.
13+
* Added full support for categories.
1314

1415
v4.0.1
1516
------

tests/test_cli.py

Lines changed: 71 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from unittest import mock
55
from unittest.mock import call
66
from unittest.mock import patch
7+
from uuid import uuid4
78

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

30-
create("test.ics", "SUMMARY:harhar\n")
31+
create("test.ics", f"UID:{uuid4()}\nSUMMARY:harhar\n")
3132
result = runner.invoke(cli, ["list"])
3233
assert not result.exception
3334
assert "harhar" in result.output
@@ -57,14 +58,14 @@ def test_no_extra_whitespace(tmpdir, runner, create):
5758
assert not result.exception
5859
assert result.output == "\n"
5960

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

6566

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

123124

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

132135

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

171174

172175
def test_default_command(tmpdir, runner, create):
173-
create("test.ics", "SUMMARY:harhar\n")
176+
create("test.ics", f"UID:{uuid4()}\nSUMMARY:harhar\n")
174177
result = runner.invoke(cli)
175178
assert not result.exception
176179
assert "harhar" in result.output
177180

178181

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

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

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

345348

346349
def test_sorting_output(tmpdir, runner, create):
347-
create("test.ics", "SUMMARY:aaa\nDUE;VALUE=DATE-TIME;TZID=ART:20160102T000000\n")
348-
create("test2.ics", "SUMMARY:bbb\nDUE;VALUE=DATE-TIME;TZID=ART:20160101T000000\n")
350+
create(
351+
"test.ics",
352+
f"UID:{uuid4()}\nSUMMARY:aaa\n"
353+
"DUE;VALUE=DATE-TIME;TZID=ART:20160102T000000\n",
354+
)
355+
create(
356+
"test2.ics",
357+
f"UID:{uuid4()}\nSUMMARY:bbb\n"
358+
"DUE;VALUE=DATE-TIME;TZID=ART:20160101T000000\n",
359+
)
349360

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

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

372383

373384
def test_sorting_null_values(tmpdir, runner, create):
374-
create("test.ics", "SUMMARY:aaa\nPRIORITY:9\n")
375-
create("test2.ics", "SUMMARY:bbb\nDUE;VALUE=DATE-TIME;TZID=ART:20160101T000000\n")
385+
create("test.ics", f"UID:{uuid4()}\nSUMMARY:aaa\nPRIORITY:9\n")
386+
create(
387+
"test2.ics",
388+
f"UID:{uuid4()}\nSUMMARY:bbb\n"
389+
"DUE;VALUE=DATE-TIME;TZID=ART:20160101T000000\n",
390+
)
376391

377392
result = runner.invoke(cli)
378393
assert not result.exception
@@ -528,7 +543,7 @@ def test_empty_list(tmpdir, runner, create):
528543

529544

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

533548
result = runner.invoke(cli, ["show", "1"])
534549
assert "Boston" in result.output
@@ -551,11 +566,13 @@ def test_sort_mixed_timezones(runner, create):
551566
"""
552567
create(
553568
"test.ics",
554-
"SUMMARY:first\nDUE;VALUE=DATE-TIME;TZID=CET:20170304T180000\n", # 1700 UTC
569+
f"UID:{uuid4()}\nSUMMARY:first\nDUE;"
570+
"VALUE=DATE-TIME;TZID=CET:20170304T180000\n", # 1700 UTC
555571
)
556572
create(
557573
"test2.ics",
558-
"SUMMARY:second\nDUE;VALUE=DATE-TIME;TZID=HST:20170304T080000\n", # 1800 UTC
574+
f"UID:{uuid4()}\nSUMMARY:second\nDUE;"
575+
"VALUE=DATE-TIME;TZID=HST:20170304T080000\n", # 1800 UTC
559576
)
560577

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

588605

589606
def test_multiple_todos_in_file(runner, create):
590-
path = create("test.ics", "SUMMARY:a\nEND:VTODO\nBEGIN:VTODO\nSUMMARY:b\n")
607+
path = create(
608+
"test.ics", f"UID:{uuid4()}\nSUMMARY:a\nEND:VTODO\nBEGIN:VTODO\nSUMMARY:b\n"
609+
)
591610

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

847866

867+
def test_new_categories_single(runner):
868+
result = runner.invoke(cli, ["new", "-l", "default", "--category", "mine", "title"])
869+
870+
assert "[mine]" in result.output
871+
872+
873+
def test_new_categories_multiple(runner):
874+
result = runner.invoke(
875+
cli, ["new", "-l", "default", "-c", "first", "-c", "second", "title"]
876+
)
877+
878+
assert "[first, second]" in result.output
879+
880+
881+
def test_list_categories_single(tmpdir, runner, create):
882+
category = "fizzbuzz"
883+
create("test.ics", f"UID:{uuid4()}\nSUMMARY:harhar\nCATEGORIES:{category}\n")
884+
result = runner.invoke(cli, ["list", "--category", category])
885+
assert not result.exception
886+
assert category in result.output
887+
888+
889+
def test_list_categories_multiple(tmpdir, runner, create):
890+
category = ["git", "gud"]
891+
create("test.ics", f"SUMMARY:harhar\nCATEGORIES:{category[0]}\n")
892+
create("test1.ics", f"SUMMARY:harhar1\nCATEGORIES:{category[1]}\n")
893+
result = runner.invoke(
894+
cli, ["list", "--category", category[0], "--category", category[1]]
895+
)
896+
assert not result.exception
897+
assert category[0] in result.output
898+
assert category[1] in result.output
899+
900+
848901
def test_show_priority(runner, todo_factory, todos):
849902
todo_factory(summary="harhar\n", priority=1)
850903

@@ -964,7 +1017,7 @@ def test_default_command_args(config, runner):
9641017
reverse=False,
9651018
lists=[],
9661019
location=None,
967-
category=None,
1020+
categories=(),
9681021
grep=None,
9691022
start=None,
9701023
startable=None,

tests/test_filtering.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from datetime import datetime
22
from datetime import timedelta
3+
from uuid import uuid4
34

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

14-
create("one.ics", "SUMMARY:haha\nPRIORITY:4\n")
15-
create("two.ics", "SUMMARY:hoho\nPRIORITY:9\n")
16-
create("three.ics", "SUMMARY:hehe\nPRIORITY:5\n")
17-
create("four.ics", "SUMMARY:huhu\n")
15+
create("one.ics", f"UID:{uuid4()}\nSUMMARY:haha\nPRIORITY:4\n")
16+
create("two.ics", f"UID:{uuid4()}\nSUMMARY:hoho\nPRIORITY:9\n")
17+
create("three.ics", f"UID:{uuid4()}\nSUMMARY:hehe\nPRIORITY:5\n")
18+
create("four.ics", f"UID:{uuid4()}\nSUMMARY:huhu\n")
1819

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

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

71-
create("one.ics", "SUMMARY:haha\nCATEGORIES:work,trip\n")
72+
create("one.ics", f"UID:{uuid4()}\nSUMMARY:haha\nCATEGORIES:work,trip\n")
7273
create("two.ics", "CATEGORIES:trip\nSUMMARY:hoho\n")
73-
create("three.ics", "SUMMARY:harhar\n")
74+
create("three.ics", f"UID:{uuid4()}\nSUMMARY:harhar\n")
7475
result = runner.invoke(cli, ["list", "--category", "work"])
7576
assert not result.exception
7677
assert "haha" in result.output
@@ -103,7 +104,7 @@ def test_grep(tmpdir, runner, create):
103104
"five.ics",
104105
"SUMMARY:research\nDESCRIPTION: Cure cancer\n",
105106
)
106-
create("six.ics", "SUMMARY:hoho\n")
107+
create("six.ics", f"UID:{uuid4()}\nSUMMARY:hoho\n")
107108
result = runner.invoke(cli, ["list", "--grep", "fun"])
108109
assert not result.exception
109110
assert "fun" in result.output
@@ -180,7 +181,8 @@ def test_due_naive(tmpdir, runner, create):
180181
due = now + timedelta(hours=i)
181182
create(
182183
f"test_{i}.ics",
183-
"SUMMARY:{}\nDUE;VALUE=DATE-TIME:{}\n".format(
184+
"UID:{}\nSUMMARY:{}\nDUE;VALUE=DATE-TIME:{}\n".format(
185+
uuid4(),
184186
i,
185187
due.strftime("%Y%m%dT%H%M%S"),
186188
),

0 commit comments

Comments
 (0)