Skip to content

Commit

Permalink
Write unit test for TaskView.get_title()
Browse files Browse the repository at this point in the history
I started to look at #1077 and I thought it would be nice to be able to unit test this type of thing.

A simple unit test for TaskView would be

* create a task
* create a view for it
* check that the title of the view is the title of the task

In the current state of affairs, this is difficult because the code that puts the Task data into the view lives in TaskEditor. But we pass a Task to the constructor of TaskView, so TaskView actually has all the data it needs. So I moved the logic there. I also moved the `is_new()` logic from the TaskEditor down to the Task.

I feel like it should be possible to eventually do this in the TaskView constructor but for now, TaskEditor calls `self.textview.set_text_from_task()` from the same place it used to run that code.
  • Loading branch information
SqAtx committed Apr 28, 2024
1 parent cf9dc27 commit 328f6f1
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 52 deletions.
6 changes: 5 additions & 1 deletion GTG/core/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,10 @@ def date_modified(self, value: Any) -> None:
self._date_modified = Date(value)


def is_new(self) -> bool:
return self.title == DEFAULT_TITLE and not self.content


@GObject.Property(type=str)
def title(self) -> str:
return self.raw_title
Expand Down Expand Up @@ -753,7 +757,7 @@ def duplicate_for_recurrent(self, task: Task) -> Task:
return new_task


def new(self, title: str = None, parent: UUID = None) -> Task:
def new(self, title: str = '', parent: UUID = None) -> Task:
"""Create a new task and add it to the store."""

tid = uuid4()
Expand Down
55 changes: 5 additions & 50 deletions GTG/gtk/editor/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
from GTG.gtk.editor.taskview import TaskView
from GTG.gtk.tag_completion import tag_filter
from GTG.gtk.colors import rgb_to_hex
from GTG.core.tasks import Task, Status, DEFAULT_TITLE
from GTG.core.tasks import Task, Status


log = logging.getLogger(__name__)
Expand Down Expand Up @@ -149,28 +149,17 @@ def __init__(self, app, task):
provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
)

# self.textview.browse_tag_cb = app.select_tag
# self.textview.new_subtask_cb = self.new_subtask
# self.textview.get_subtasks_cb = task.get_children
# self.textview.delete_subtask_cb = self.remove_subtask
# self.textview.rename_subtask_cb = self.rename_subtask
# self.textview.open_subtask_cb = self.open_subtask
# self.textview.save_cb = self.light_save
# self.textview.add_tasktag_cb = self.tag_added
# self.textview.remove_tasktag_cb = self.tag_removed
# self.textview.refresh_cb = self.refresh_editor
# self.textview.get_tagslist_cb = task.get_tags_name
# self.textview.tid = task.id

self.textview.browse_tag_cb = app.select_tag
self.textview.new_subtask_cb = self.new_subtask
# self.textview.get_subtasks_cb = task.get_children
self.textview.delete_subtask_cb = self.remove_subtask
self.textview.rename_subtask_cb = self.rename_subtask
self.textview.open_subtask_cb = self.open_subtask
self.textview.save_cb = self.light_save
self.textview.add_tasktag_cb = self.tag_added
self.textview.remove_tasktag_cb = self.tag_removed
self.textview.refresh_cb = self.refresh_editor
# self.textview.get_tagslist_cb = task.get_tags_name
self.textview.tid = task.id

# Voila! it's done
Expand All @@ -179,40 +168,7 @@ def __init__(self, app, task):
textview_focus_controller.connect("leave", self.on_textview_focus_out)
self.textview.add_controller(textview_focus_controller)

tags = task.tags
text = self.task.content
title = self.task.title

# Insert text and tags as a non_undoable action, otherwise
# the user can CTRL+Z even this inserts.
self.textview.buffer.begin_irreversible_action()
self.textview.buffer.set_text(f"{title}\n")

if text:
self.textview.insert(text)

# Insert any remaining tags
if tags:
tag_names = [t.name for t in tags]
self.textview.insert_tags(tag_names)
else:
# If not text, we insert tags
if tags:
tag_names = [t.name for t in tags]
self.textview.insert_tags(tag_names)
start = self.textview.buffer.get_end_iter()
self.textview.buffer.insert(start, '\n')

# Insert subtasks if they weren't inserted in the text
subtasks = task.children
for sub in subtasks:
if sub.id not in self.textview.subtasks['tags']:
self.textview.insert_existing_subtask(sub)

if self.is_new():
self.textview.select_title()

self.textview.buffer.end_irreversible_action()
self.textview.set_text_from_task()

# Connect search field to tags popup
self.tags_tree.set_search_entry(self.tags_entry)
Expand Down Expand Up @@ -873,8 +829,7 @@ def on_window_focus_change(self, window, gparam):


def is_new(self) -> bool:
return (self.task.title == DEFAULT_TITLE
and self.textview.get_text() == '')
return self.task.is_new()


def destruction(self, _=None):
Expand Down
32 changes: 32 additions & 0 deletions GTG/gtk/editor/taskview.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,38 @@ def __init__(self, ds: Datastore, task, clipboard, dark) -> None:
press_gesture.connect('begin', self.on_single_begin)
self.add_controller(press_gesture)

def set_text_from_task(self) -> None:
"""Sets the text of the view, from the text of the task"""
# Insert text and tags as a non_undoable action, otherwise
# the user can CTRL+Z even this inserts.
self.buffer.begin_irreversible_action()
self.buffer.set_text(f"{self.task.title}\n")

if self.task.content:
self.insert(self.task.content)

# Insert any remaining tags
if self.task.tags:
tag_names = [t.name for t in self.task.tags]
self.insert_tags(tag_names)
else:
# If not text, we insert tags
if self.task.tags:
tag_names = [t.name for t in self.task.tags]
self.insert_tags(tag_names)
start = self.buffer.get_end_iter()
self.buffer.insert(start, '\n')

# Insert subtasks if they weren't inserted in the text
subtasks = self.task.children
for sub in subtasks:
if sub.id not in self.subtasks['tags']:
self.insert_existing_subtask(sub)

if self.task.is_new():
self.select_title()

self.buffer.end_irreversible_action()

def on_modified(self, buffer: Gtk.TextBuffer) -> None:
"""Called every time the text buffer changes."""
Expand Down
16 changes: 16 additions & 0 deletions tests/core/test_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,22 @@

class TestTask(TestCase):

def test_default_task_from_store_is_new(self):
task = TaskStore().new()

self.assertTrue(task.is_new())

def test_task_with_content_is_not_new(self):
task = TaskStore().new()
task.content = 'foobar'

self.assertFalse(task.is_new())

def test_task_with_title_is_not_new(self):
task = TaskStore().new(title='My new task')

self.assertFalse(task.is_new())

def test_title(self):
task = Task(id=uuid4(), title='\tMy Title\n')

Expand Down
17 changes: 16 additions & 1 deletion tests/core/test_taskview.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@
# -----------------------------------------------------------------------------

import re
from uuid import uuid4
from unittest import TestCase
from GTG.gtk.editor.taskview import TAG_REGEX
from GTG.core.datastore import Datastore
from GTG.core.tasks import Task
from GTG.gtk.editor.taskview import TaskView, TAG_REGEX


class TestTaskView(TestCase):
Expand All @@ -41,3 +44,15 @@ def test_no_detect_tags(self):
matches = re.findall(TAG_REGEX, content)

self.assertEqual([], matches)

def test_get_title(self):
task_title = 'Very important task'
task = Task(id = uuid4(), title=task_title)
view = TaskView(Datastore(), task, None, False)
view.refresh_cb = lambda x: x # Refresh CB that does nothing
view.set_text_from_task()
view.detect_title()

view_title = view.get_title()

self.assertEqual(view_title, task_title)

0 comments on commit 328f6f1

Please sign in to comment.