def test_Filer_delete_existing_file( tmp_file: Filer, to_del: str, expected: List[List[str]], ) -> None: """Run Filer to delete a line from an existing file This is parametrised to check conditions where a line is not deleted """ tmp_file.delete(to_del) for line, entry in zip(tmp_file.read(), expected): assert line == entry
def test_Filer_create( tmp_path: Path, create: bool, expected: List[List[Optional[str]]], ) -> None: """Run Filer to read a file that does not exist This is parametrize to test that if fails if `create = False` but passes when `create = True` """ file = Filer(tmp_path / "tmp.tsv", create=create) assert file.read() == expected
def test_Filer_sort_existing_file( tmp_file: Filer, header: bool, expected: List[List[str]], ) -> None: """Run Filer to sort an existing file This is parametrised to check that headers are treated properly """ if not header: # As tmp file comes with header, delete if necessary tmp_file.delete("Rank") tmp_file.sort([1], header=header) for line, entry in zip(tmp_file.read(), expected): assert line == entry
def test_to_done(tmp_file: Filer, capsys): """Check that task are appropriately deleted from the TODO file""" to( argparse.Namespace(func=done, file=tmp_file, create=True, tasks=["nothing", "Old task"])) out, err = capsys.readouterr() assert tmp_file.read() == expected assert err == "" assert ( out == 'Task "nothing" not in TODOs...\nTask "Old task" successfully deleted!\n' )
def test_to_doing(sort: str, expected: str, tmp_file: Filer, capsys): """Run to doing with existing custom file Parametrised to test situations where `--sort` is/isn't passed""" to( argparse.Namespace( func=doing, file=tmp_file, sort=sort, number=5, edit=False, reminder=False, ) ) out, err = capsys.readouterr() assert tmp_file.read() == expected assert err == "" assert out == "\n".join(["\t".join(i) for i in expected]) + "\n"
def test_to_do(sort: str, expected: str, tmp_file: Filer, capsys): """Check that tasks are appropriately added and sorted Parametrized to check various calls to the `--sort` flag""" to( argparse.Namespace(func=do, file=tmp_file, sort=sort, rank=1, tasks=["Newer task"])) out, err = capsys.readouterr() assert tmp_file.read() == expected assert err == "" assert out == "1 task(s) added!\n"
def doctest_filer_example(doctest_namespace: Dict[str, Filer], tmp_path: Path) -> None: """Fixture for instantiating an example Filer for use in doctests Parameters ---------- doctest_namespace : Dict[str, Filer] `pytest.fixture` holding variables to be used in doctests tmp_path : Path `pytest.fixture` containing a temporary file path Returns ------- None """ doctest_namespace["example"] = Filer(tmp_path / ".TODO.tsv", create=True)
def tmp_file(tmp_path: Path) -> Filer: """Fixture for automating setup of files Parameters ---------- tmp_path : Path pytest.fixture. Where to create the file Returns ------- Path An instantiated tsv file """ tmp = tmp_path / "tmp.tsv" tmp.write_text("ID\tRank\tDate\tTask\n1\t2\t2019-09-20 20:56\tOld task\n" "2\t1\t2019-09-24 12:57\tNew task\n") return Filer(tmp)
def test_Filer_write_col_error(tmp_file: Filer) -> None: """ Check that `Filer.write_col` raises an `IndexError` if col is the wrong length""" with pytest.raises(IndexError): tmp_file.write_col(list("abcdefghijk"))
def test_Filer_append_existing_file(tmp_file: Filer) -> None: """Run Filer to append to an existing file""" added = [["3", "3", "2020-06-24 08:53", "Newer task"]] tmp_file.append(added) for line, entry in zip(tmp_file.read(), results_txt + added): assert line == entry
def test_Filer_write_existing_file(tmp_file: Filer) -> None: """Run Filer to write to an existing file""" written = [["3", "3", "2020-06-24 08:53", "Newer task"]] tmp_file.write(written) for line, entry in zip(tmp_file.read(), written): assert line == entry
def test_Filer_read_existing_file(tmp_file: Filer) -> None: """Run Filer to read an existing file""" for line, entry in zip(tmp_file.read(), results_txt): assert line == entry
The Filer object containing the TODOs. It first checks to see if the env var TODO_FILE is set. If it is, it looks there. If not, it defaults to ~/.todo.tsv. A hidden file is used to prevent clutter. """ import argparse import os from pathlib import Path import poetry_version from helpers.filer import Filer from subcommands.do import do from subcommands.doing import doing from subcommands.done import done __version__ = poetry_version.extract(source_file=__file__) __todo__ = Filer(os.environ.get("TODO_FILE", Path.home() / ".todo.tsv"), create=True) # The root command to_parser = argparse.ArgumentParser(prog="to") to_parser.add_argument( "-v", "--version", action="version", version=f"ToDonePy v{__version__}", help="Display the version and exit", ) to_parser.add_argument( "-f", "--file", default=__todo__, type=Filer, help="Your TODO file", ) to_parser.add_argument( "-s",