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

Write unit test for TaskView.get_title() #1083

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@ jobs:
- name: Run unit tests with Pytest
run: |
export PYTHONPATH=${PWD}/inst/lib/python3.9/site-packages
pytest
# Provide a fake display server, for tests that need one
xvfb-run pytest
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: Optional[UUID] = None) -> Task:
def new(self, title: str = '', parent: Optional[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 @@ -39,7 +39,7 @@
from GTG.gtk.editor.recurring_menu import RecurringMenu
from GTG.gtk.editor.taskview import TaskView
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 @@ -148,28 +148,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 @@ -178,40 +167,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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block of code has moved to the TaskView class. The logic hasn't changed besides the way the objects are named (self.insert() instead of self.textview.insert() etc) and the fact that the TextView calls is_new() on the task object.

# 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 @@ -872,8 +828,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 @@ -28,6 +28,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
19 changes: 18 additions & 1 deletion tests/core/test_taskview.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
# -----------------------------------------------------------------------------

import os
import pytest
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 +46,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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 3 lines can probably be encapsulated into a create_task_view_from_task() test helper, but I can do that when I add another test.

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)