Added new methods on TaskList.

This commit is contained in:
JamesClonk 2014-01-13 20:27:58 +01:00
parent c1f16b56a5
commit a0e8e1801d
4 changed files with 239 additions and 15 deletions

View File

@ -39,6 +39,15 @@ go-todotxt requires Go1.1 or higher.
fmt.Printf("Task 3: %v\n", tasklist[2]) fmt.Printf("Task 3: %v\n", tasklist[2])
fmt.Printf("Task 4, has priority: %v\n\n", tasklist[3].HasPriority()) fmt.Printf("Task 4, has priority: %v\n\n", tasklist[3].HasPriority())
fmt.Print(tasklist) fmt.Print(tasklist)
// Filter list to get only completed tasks
completedList := testTasklist.Filter(func(t Task) bool {
if t.Completed {
return true
}
return false
})
fmt.Print(completedList)
} }
``` ```

View File

@ -103,10 +103,10 @@ func (task Task) String() string {
} }
// NewTask creates a new empty Task with default values. (CreatedDate is set to Now()) // NewTask creates a new empty Task with default values. (CreatedDate is set to Now())
func NewTask() *Task { func NewTask() Task {
task := Task{} task := Task{}
task.CreatedDate = time.Now() task.CreatedDate = time.Now()
return &task return task
} }
// ParseTask parses the input text string into a Task struct. // ParseTask parses the input text string into a Task struct.

View File

@ -10,6 +10,7 @@ package todotxt
import ( import (
"bufio" "bufio"
"errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
@ -28,7 +29,13 @@ var (
IgnoreComments = true IgnoreComments = true
) )
// String returns a complete tasklist string in todo.txt format. // NewTaskList creates a new empty TaskList.
func NewTaskList() TaskList {
tasklist := TaskList{}
return tasklist
}
// String returns a complete list of tasks in todo.txt format.
func (tasklist TaskList) String() (text string) { func (tasklist TaskList) String() (text string) {
for _, task := range tasklist { for _, task := range tasklist {
text += fmt.Sprintf("%s\n", task.String()) text += fmt.Sprintf("%s\n", task.String())
@ -36,8 +43,8 @@ func (tasklist TaskList) String() (text string) {
return text return text
} }
// AddTask appends a task to the current TaskList, and takes care to set the Task.Id correctly, modifying the Task by the given pointer! // AddTask appends a task to the current TaskList and takes care to set the Task.Id correctly, modifying the Task by the given pointer!
func (tasklist *TaskList) AddTask(task *Task) (err error) { func (tasklist *TaskList) AddTask(task *Task) {
task.Id = 0 task.Id = 0
for _, t := range *tasklist { for _, t := range *tasklist {
if t.Id > task.Id { if t.Id > task.Id {
@ -47,7 +54,70 @@ func (tasklist *TaskList) AddTask(task *Task) (err error) {
task.Id += 1 task.Id += 1
*tasklist = append(*tasklist, *task) *tasklist = append(*tasklist, *task)
return }
// GetTask returns task by given task 'id' from the TaskList. Returns an error if task could not be found.
func (tasklist *TaskList) GetTask(id int) (*Task, error) {
for _, t := range *tasklist {
if t.Id == id {
return &t, nil
}
}
return nil, errors.New("task not found")
}
// RemoveTaskById removes any task with given task 'id' from the TaskList.
// Returns an error if no task was removed.
func (tasklist *TaskList) RemoveTaskById(id int) error {
var newList TaskList
found := false
for _, t := range *tasklist {
if t.Id != id {
newList = append(newList, t)
} else {
found = true
}
}
if !found {
return errors.New("task not found")
}
*tasklist = newList
return nil
}
// RemoveTask removes any task from the TaskList with the same String representation as the given task.
// Returns an error if no task was removed.
func (tasklist *TaskList) RemoveTask(task Task) error {
var newList TaskList
found := false
for _, t := range *tasklist {
if t.String() != task.String() {
newList = append(newList, t)
} else {
found = true
}
}
if !found {
return errors.New("task not found")
}
*tasklist = newList
return nil
}
// Filter filters the current TaskList for the given predicate (a function that takes a task as input and returns a bool),
// and returns a new TaskList. The original TaskList is not modified.
func (tasklist *TaskList) Filter(predicate func(Task) bool) *TaskList {
var newList TaskList
for _, t := range *tasklist {
if predicate(t) {
newList = append(newList, t)
}
}
return &newList
} }
// LoadFromFile loads a TaskList from *os.File. // LoadFromFile loads a TaskList from *os.File.

View File

@ -205,7 +205,13 @@ func TestTaskListWriteFilename(t *testing.T) {
} }
func TestNewTaskList(t *testing.T) { func TestNewTaskList(t *testing.T) {
t.Fail() testTasklist := NewTaskList()
testExpected = 0
testGot = len(testTasklist)
if testGot != testExpected {
t.Errorf("Expected TaskList to contain %d tasks, but got %d", testExpected, testGot)
}
} }
func TestTaskListCount(t *testing.T) { func TestTaskListCount(t *testing.T) {
@ -226,7 +232,8 @@ func TestTaskListAddTask(t *testing.T) {
} }
// add new empty task // add new empty task
testTasklist.AddTask(NewTask()) task := NewTask()
testTasklist.AddTask(&task)
testExpected = 64 testExpected = 64
testGot = len(testTasklist) testGot = len(testTasklist)
@ -299,21 +306,159 @@ func TestTaskListAddTask(t *testing.T) {
taskId++ taskId++
} }
func TestTaskListGetTask(t *testing.T) {
if err := testTasklist.LoadFromFilename(testInputTasklist); err != nil {
t.Fatal(err)
}
taskId := 3
task, err := testTasklist.GetTask(taskId)
if err != nil {
t.Error(err)
}
testExpected = "(B) 2013-12-01 Outline chapter 5 @Computer +Novel Level:5 private:false due:2014-02-17"
testGot = task.String()
if testGot != testExpected {
t.Errorf("Expected Task[%d] to be [%s], but got [%s]", taskId, testExpected, testGot)
}
testExpected = 3
testGot = testTasklist[taskId-1].Id
if testGot != testExpected {
t.Errorf("Expected Task[%d] to be [%d], but got [%d]", taskId, testExpected, testGot)
}
taskId++
}
func TestTaskListRemoveTaskById(t *testing.T) { func TestTaskListRemoveTaskById(t *testing.T) {
t.Fail() if err := testTasklist.LoadFromFilename(testInputTasklist); err != nil {
t.Fatal(err)
}
taskId := 10
if err := testTasklist.RemoveTaskById(taskId); err != nil {
t.Error(err)
}
testExpected = 62
testGot = len(testTasklist)
if testGot != testExpected {
t.Errorf("Expected TaskList to contain %d tasks, but got %d", testExpected, testGot)
}
task, err := testTasklist.GetTask(taskId)
if err == nil || task != nil {
t.Errorf("Expected no Task to be found anymore, but got %v", task)
}
taskId = 27
if err := testTasklist.RemoveTaskById(taskId); err != nil {
t.Error(err)
}
testExpected = 61
testGot = len(testTasklist)
if testGot != testExpected {
t.Errorf("Expected TaskList to contain %d tasks, but got %d", testExpected, testGot)
}
task, err = testTasklist.GetTask(taskId)
if err == nil || task != nil {
t.Errorf("Expected no Task to be found anymore, but got %v", task)
}
taskId = 99
if err := testTasklist.RemoveTaskById(taskId); err == nil {
t.Errorf("Expected no Task to be found for removal")
}
} }
func TestTaskListRemoveTask(t *testing.T) { func TestTaskListRemoveTask(t *testing.T) {
// removes by comparing Task.String() with each other if err := testTasklist.LoadFromFilename(testInputTasklist); err != nil {
t.Fail() t.Fatal(err)
}
taskId := 52 // Is "unique" in tasklist
task, err := testTasklist.GetTask(taskId)
if err != nil {
t.Error(err)
}
if err := testTasklist.RemoveTask(*task); err != nil {
t.Error(err)
}
testExpected = 62
testGot = len(testTasklist)
if testGot != testExpected {
t.Errorf("Expected TaskList to contain %d tasks, but got %d", testExpected, testGot)
}
task, err = testTasklist.GetTask(taskId)
if err == nil || task != nil {
t.Errorf("Expected no Task to be found anymore, but got %v", task)
}
taskId = 2 // Exists 3 times in tasklist
task, err = testTasklist.GetTask(taskId)
if err != nil {
t.Error(err)
}
if err := testTasklist.RemoveTask(*task); err != nil {
t.Error(err)
}
testExpected = 59
testGot = len(testTasklist)
if testGot != testExpected {
t.Errorf("Expected TaskList to contain %d tasks, but got %d", testExpected, testGot)
}
task, err = testTasklist.GetTask(taskId)
if err == nil || task != nil {
t.Errorf("Expected no Task to be found anymore, but got %v", task)
}
if err := testTasklist.RemoveTask(NewTask()); err == nil {
t.Errorf("Expected no Task to be found for removal")
}
} }
func TestTaskListFilter(t *testing.T) { func TestTaskListFilter(t *testing.T) {
t.Fail() if err := testTasklist.LoadFromFilename(testInputTasklist); err != nil {
} t.Fatal(err)
}
func TestTaskListFilterNot(t *testing.T) { // Filter list to get only completed tasks
t.Fail() completedList := testTasklist.Filter(func(t Task) bool {
if t.Completed {
return true
}
return false
})
testExpected = 33
testGot = len(*completedList)
if testGot != testExpected {
t.Errorf("Expected TaskList to contain %d tasks, but got %d", testExpected, testGot)
}
// Filter list to get only tasks with a due date
dueDateList := testTasklist.Filter(func(t Task) bool {
if t.HasDueDate() {
return true
}
return false
})
testExpected = 26
testGot = len(*dueDateList)
if testGot != testExpected {
t.Errorf("Expected TaskList to contain %d tasks, but got %d", testExpected, testGot)
}
// Filter list to get only tasks with "B" priority
prioBList := testTasklist.Filter(func(t Task) bool {
if t.HasPriority() && t.Priority == "B" {
return true
}
return false
})
testExpected = 17
testGot = len(*prioBList)
if testGot != testExpected {
t.Errorf("Expected TaskList to contain %d tasks, but got %d", testExpected, testGot)
}
} }
func TestTaskListReadErrors(t *testing.T) { func TestTaskListReadErrors(t *testing.T) {