2do 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.ruby-version +1 -0
- data/CHANGELOG +3 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +67 -0
- data/Rakefile +9 -0
- data/bin/todo +88 -0
- data/lib/todo.rb +57 -0
- data/lib/todo/list.rb +110 -0
- data/lib/todo/list_item.rb +34 -0
- data/lib/todo/presenter.rb +71 -0
- data/lib/todo/version.rb +3 -0
- data/test/todo/list_item_test.rb +34 -0
- data/test/todo/list_test.rb +77 -0
- data/test/todo/presenter_test.rb +70 -0
- data/test/todo_test.rb +62 -0
- data/todo.gemspec +26 -0
- metadata +138 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5b634ce5130c195a6c86c8eeaacb3d15c9eb8e5e
|
4
|
+
data.tar.gz: 5ed204b515b078ba093b5df6e151a16dd7341d6a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 252502fbddf7a9bb96f4dc486f1321f45991c21319647c6febf3cd63fdb7272e9323d0c5981c3cb4e0635f62180861fc60aef0bcccec9be9339b1c6c9cf97b91
|
7
|
+
data.tar.gz: 527bbeb605d171713fd95da3798905d3b27f9640678328b86506d9adeeb962031105ba23542a899f4b93fe8ef04d1fa99a0c2a4e2570be27c8f69dcf981f9220
|
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.1.0
|
data/CHANGELOG
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Kavinder Dhaliwal
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# Todo ( gem '2do')
|
2
|
+
|
3
|
+
##The Problem
|
4
|
+
|
5
|
+
I find it hard to manage my todo list in any application (Evernote, Trello, Wunderlist). It's just a mental barrier to switch context open an application, find the list or notebook and then finally type in the todo item. This gem aims to solve my problem by providing a command line alternative that is simple to add to a list, create a new list or sublist and check items off a list.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem '2do'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install 2do
|
20
|
+
|
21
|
+
- **Setup**
|
22
|
+
|
23
|
+
In order to setup todo on your machine you'll need to do the following:
|
24
|
+
|
25
|
+
-Todo persists the lists to $HOME/todo/ so make sure that is available and writable
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
Todo can be used in the following ways:
|
30
|
+
|
31
|
+
1. Add a task to the general list:
|
32
|
+
|
33
|
+
`todo add 'get some milk'`
|
34
|
+
|
35
|
+
2. Add a task to the general list with priority:
|
36
|
+
|
37
|
+
`todo add 'get some milk' -p high`
|
38
|
+
|
39
|
+
This will push the item to the top of the list.
|
40
|
+
|
41
|
+
3. Add a task to a specific list:
|
42
|
+
|
43
|
+
`todo add 'get some milk' -l groceries`
|
44
|
+
|
45
|
+
4. Recall a list
|
46
|
+
|
47
|
+
`todo lists groceries`
|
48
|
+
|
49
|
+
This returnes
|
50
|
+
|
51
|
+
1. `'get some milk' | due date: tomorrow | priority: high`
|
52
|
+
|
53
|
+
6. Mark a task as done
|
54
|
+
|
55
|
+
`todo finish 'get some milk' -l groceries`
|
56
|
+
|
57
|
+
7. Delete a task
|
58
|
+
|
59
|
+
`todo remove 'get some milk' -l groceries`
|
60
|
+
|
61
|
+
## Contributing
|
62
|
+
|
63
|
+
1. Fork it ( http://github.com/<my-github-username>/todo/fork )
|
64
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
65
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
66
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
67
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/todo
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
require 'todo'
|
4
|
+
require 'main'
|
5
|
+
|
6
|
+
Main {
|
7
|
+
|
8
|
+
mode "add" do
|
9
|
+
argument("task"){
|
10
|
+
cast :string
|
11
|
+
}
|
12
|
+
option('list', 'l'){
|
13
|
+
argument :optional
|
14
|
+
description 'pass a list to add a task to'
|
15
|
+
}
|
16
|
+
|
17
|
+
def run
|
18
|
+
app = Todo::Application.new(persistent: true)
|
19
|
+
app.add(name:params['task'].value, list: params['list'].value)
|
20
|
+
app.tasks
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
mode "tasks" do
|
25
|
+
|
26
|
+
option("list", 'l') {
|
27
|
+
argument :optional
|
28
|
+
}
|
29
|
+
|
30
|
+
def run
|
31
|
+
app = Todo::Application.new(persistent: true)
|
32
|
+
app.tasks(verbose: true, list: params["list"].value)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
mode "remove" do
|
37
|
+
argument("task"){
|
38
|
+
cast :string
|
39
|
+
}
|
40
|
+
option("list", "l"){
|
41
|
+
argument :optional
|
42
|
+
}
|
43
|
+
def run
|
44
|
+
app = Todo::Application.new(persistent: true)
|
45
|
+
allowed = ["Y", "N", "yes", "no"]
|
46
|
+
allowed_positives = ["Y", "yes", "y", "Yes"]
|
47
|
+
allowed_negatives = ["N", "no", "n", "No"]
|
48
|
+
command =""
|
49
|
+
until(allowed_positives.include?(command) || allowed_negatives.include?(command))
|
50
|
+
print "Are you sure you want to remove this task? (Y/N) "
|
51
|
+
command = stdin.gets.chomp
|
52
|
+
end
|
53
|
+
if allowed_positives.include?(command)
|
54
|
+
task = params["task"].value
|
55
|
+
app.remove(task)
|
56
|
+
puts "task:#{task} removed"
|
57
|
+
app.tasks(verbose: true)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
mode "finish" do
|
63
|
+
|
64
|
+
argument("task") {
|
65
|
+
cast :string
|
66
|
+
}
|
67
|
+
option("list", "l") {
|
68
|
+
argument :optional
|
69
|
+
}
|
70
|
+
def run
|
71
|
+
app = Todo::Application.new(persistent: true)
|
72
|
+
app.finish(params["task"].value, list: params["list"].value)
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
mode "lists" do
|
78
|
+
argument("list"){
|
79
|
+
optional
|
80
|
+
cast :string
|
81
|
+
description "the sublist to access"
|
82
|
+
}
|
83
|
+
def run
|
84
|
+
app =Todo::Application.new(persistent: true)
|
85
|
+
params["list"].given? ? app.access_list(params["list"].value) : app.lists
|
86
|
+
end
|
87
|
+
end
|
88
|
+
}
|
data/lib/todo.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
#TODO: Read PR article about require and require relative
|
2
|
+
|
3
|
+
require_relative "todo/version"
|
4
|
+
require_relative "todo/version"
|
5
|
+
require_relative "todo/list"
|
6
|
+
require_relative 'todo/presenter'
|
7
|
+
module Todo
|
8
|
+
|
9
|
+
class Application
|
10
|
+
|
11
|
+
def initialize(persistent: false)
|
12
|
+
@list = init_list(persistent)
|
13
|
+
@presenter = Todo::Presenter.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def add(name:, **options)
|
17
|
+
@list.add(name: name, priority: options[:priority], list: options[:list])
|
18
|
+
end
|
19
|
+
|
20
|
+
def finish(task_name, **options)
|
21
|
+
if options[:list]
|
22
|
+
access_list(options[:list]).finish(task_name)
|
23
|
+
else
|
24
|
+
@list.finish(task_name)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def remove(task_name)
|
29
|
+
@list.remove(task_name)
|
30
|
+
end
|
31
|
+
|
32
|
+
def tasks(options={})
|
33
|
+
item = options[:list] ? access_list(options[:list]) : @list
|
34
|
+
return "no such list" unless item
|
35
|
+
@presenter.present(item: item, info: :tasks, level: options[:level])
|
36
|
+
end
|
37
|
+
|
38
|
+
def lists
|
39
|
+
@presenter.present(item: @list, info: :lists)
|
40
|
+
end
|
41
|
+
|
42
|
+
def access_list(list_name)
|
43
|
+
@list.access_list(list_name)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def init_list(persistent)
|
49
|
+
if persistent
|
50
|
+
Todo::List.load
|
51
|
+
else
|
52
|
+
Todo::List.new
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
data/lib/todo/list.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require_relative "list_item"
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Todo
|
5
|
+
class List
|
6
|
+
DIR_PATH = File.join(Dir.home, "todo")
|
7
|
+
FILE_PATH = File.join(DIR_PATH, "todo.yml")
|
8
|
+
attr_reader :tasks, :lists, :name
|
9
|
+
def initialize(list_name=nil, persistent:false)
|
10
|
+
@tasks = []
|
11
|
+
@name = list_name || 'undefined'
|
12
|
+
@lists = []
|
13
|
+
@persistent = persistent
|
14
|
+
end
|
15
|
+
|
16
|
+
def add(name:,**options)
|
17
|
+
if options[:list]
|
18
|
+
add_to_list(name, options)
|
19
|
+
else
|
20
|
+
add_task(name, options)
|
21
|
+
end
|
22
|
+
update
|
23
|
+
end
|
24
|
+
|
25
|
+
def finish(name)
|
26
|
+
@tasks.each { |t| t.finish! if t.name == name }
|
27
|
+
update
|
28
|
+
end
|
29
|
+
|
30
|
+
def remove(name)
|
31
|
+
@tasks.delete_if{|t| t.name == name}
|
32
|
+
update
|
33
|
+
all
|
34
|
+
end
|
35
|
+
|
36
|
+
def all(options={})
|
37
|
+
@tasks
|
38
|
+
end
|
39
|
+
|
40
|
+
def lists
|
41
|
+
@lists.map{ |l| l.name }
|
42
|
+
end
|
43
|
+
|
44
|
+
def access_list(list_name)
|
45
|
+
list_with_name(list_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_h
|
49
|
+
{
|
50
|
+
name: name,
|
51
|
+
tasks: @tasks.map{ |t| t.to_h },
|
52
|
+
lists: @lists.map{ |l| l.to_h }
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
def type
|
57
|
+
"list"
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.load
|
61
|
+
if File.exists?(FILE_PATH)
|
62
|
+
YAML.load(File.open(FILE_PATH))
|
63
|
+
else
|
64
|
+
Dir.mkdir(DIR_PATH) unless Dir.exists?(DIR_PATH)
|
65
|
+
self.new(persistent: true)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def update
|
72
|
+
save if @persistent
|
73
|
+
end
|
74
|
+
|
75
|
+
def save
|
76
|
+
return unless @name == "undefined"
|
77
|
+
File.open(FILE_PATH, "w") do |f|
|
78
|
+
f.write YAML.dump(self)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def create_or_find(list_name)
|
83
|
+
list = list_with_name(list_name)
|
84
|
+
if list
|
85
|
+
list
|
86
|
+
else
|
87
|
+
list = Todo::List.new(list_name)
|
88
|
+
@lists << list
|
89
|
+
list
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def list_with_name(list_name)
|
94
|
+
index = @lists.find_index{ |l| l.name == list_name }
|
95
|
+
index ? @lists[index] : index
|
96
|
+
end
|
97
|
+
|
98
|
+
def add_task(name, options)
|
99
|
+
@tasks << Todo::ListItem.new(name: name, priority: options[:priority])
|
100
|
+
end
|
101
|
+
|
102
|
+
def add_to_list(name, options)
|
103
|
+
list = create_or_find(options[:list])
|
104
|
+
options.delete(:list)
|
105
|
+
list.add(name: name, priority: options[:priority])
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Todo
|
2
|
+
class ListItem
|
3
|
+
|
4
|
+
attr_reader :name, :priority
|
5
|
+
def initialize(name:, priority: nil)
|
6
|
+
@name = name
|
7
|
+
@priority = priority
|
8
|
+
@finished = false
|
9
|
+
end
|
10
|
+
|
11
|
+
def details
|
12
|
+
n = "#{name}"
|
13
|
+
priority = @priority ? "priority: #{priority}" : nil
|
14
|
+
finished = @finished ? "----FINISHED----" : nil
|
15
|
+
[n, priority, finished].delete_if { |i| i.nil? }.join(" | ")
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_h
|
19
|
+
{
|
20
|
+
name: name,
|
21
|
+
priority: priority,
|
22
|
+
finished: @finished
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def finished?
|
27
|
+
@finished
|
28
|
+
end
|
29
|
+
|
30
|
+
def finish!
|
31
|
+
@finished = true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Todo
|
2
|
+
class Presenter
|
3
|
+
|
4
|
+
def present(item:,**options)
|
5
|
+
@presentable = item
|
6
|
+
@level = options[:level] ||= :basic
|
7
|
+
@info = options.fetch(:info)
|
8
|
+
@exclude = options[:exclude]
|
9
|
+
print send("render_#{@presentable.type}_#{@info}_#{@level}", @presentable)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
#LIST PRESENTATION
|
15
|
+
def render_list_lists_basic(presentable)
|
16
|
+
lists = presentable.to_h[:lists]
|
17
|
+
output = "Lists\n"
|
18
|
+
lists.each_with_index do |t, i|
|
19
|
+
order = i + 1
|
20
|
+
output << "#{order}. #{t[:name]}\n"
|
21
|
+
end
|
22
|
+
output
|
23
|
+
end
|
24
|
+
|
25
|
+
def render_list_lists_verbose(presentable)
|
26
|
+
lists = presentable.to_h[:lists]
|
27
|
+
output = "Lists\n"
|
28
|
+
lists.each_with_index do |t, i|
|
29
|
+
order = i + 1
|
30
|
+
output << "#{order}. #{t[:name]} | tasks: #{t[:tasks].count}\n"
|
31
|
+
end
|
32
|
+
output
|
33
|
+
end
|
34
|
+
|
35
|
+
#TASK PRESENTATION
|
36
|
+
def render_list_tasks_basic(presentable)
|
37
|
+
tasks = presentable_tasks
|
38
|
+
output = "Tasks\n"
|
39
|
+
tasks.each_with_index do |t,i|
|
40
|
+
order = i + 1
|
41
|
+
output << "#{order}. #{t[:name]}\n"
|
42
|
+
end
|
43
|
+
output
|
44
|
+
end
|
45
|
+
|
46
|
+
def render_list_tasks_verbose(presentable)
|
47
|
+
tasks = presentable_tasks
|
48
|
+
output = "Tasks\n"
|
49
|
+
tasks.each_with_index do |t, i|
|
50
|
+
order = i + 1
|
51
|
+
substring = "#{order}. #{t.delete(:name)} "
|
52
|
+
substring << "| ---- FINISHED ----" if t.delete(:finished)
|
53
|
+
t.each do |key, value|
|
54
|
+
if value
|
55
|
+
substring << "| #{key}: #{value}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
substring << "\n"
|
59
|
+
output << substring
|
60
|
+
end
|
61
|
+
output
|
62
|
+
end
|
63
|
+
|
64
|
+
def presentable_tasks
|
65
|
+
@data = @presentable.to_h[:tasks]
|
66
|
+
@data = @data.select { |item| item[:finished] == false } if @exclude == :finished
|
67
|
+
@data = @data.select { |item| item[:finished] == true } if @exclude == :open
|
68
|
+
@data
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/todo/version.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative "../../lib/todo/list_item"
|
2
|
+
#TODO: Does minitest have a spec_helper convention
|
3
|
+
require "minitest/autorun"
|
4
|
+
|
5
|
+
class ListItemTest < MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
def test_initializing_minimal_list_item
|
8
|
+
assert_instance_of(Todo::ListItem, Todo::ListItem.new(name: "my item"))
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_to_h
|
12
|
+
li = Todo::ListItem.new(name: 'my item', priority: 'high')
|
13
|
+
assert_equal({name: 'my item', priority: "high", finished: false}, li.to_h)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_marking_as_finished
|
17
|
+
li = Todo::ListItem.new(name: "my item")
|
18
|
+
assert_equal(false, li.finished?)
|
19
|
+
li.finish!
|
20
|
+
assert_equal(true, li.finished?)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_finished_to_s_output
|
24
|
+
li = Todo::ListItem.new(name: 'my item')
|
25
|
+
li.finish!
|
26
|
+
assert_equal('my item | ----FINISHED----', li.details)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_output_without_finished
|
30
|
+
li = Todo::ListItem.new(name: 'my item')
|
31
|
+
assert_equal('my item', li.details)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require_relative '../../lib/todo/list'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
class ListTest < MiniTest::Unit::TestCase
|
5
|
+
|
6
|
+
def teardown
|
7
|
+
file_path = File.join(Dir.home, "todo", "todo.yml")
|
8
|
+
File.delete(file_path) if File.exists?(file_path)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_inital_list_state
|
12
|
+
list = Todo::List.new
|
13
|
+
assert_equal([], list.tasks)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_list_with_name
|
17
|
+
list = Todo::List.new("named list")
|
18
|
+
assert_equal("named list", list.name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_list_adds_list_item_objects
|
22
|
+
list = Todo::List.new
|
23
|
+
list.add(name: "my task")
|
24
|
+
assert_instance_of(Todo::ListItem, list.all[0])
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_adding_sublists
|
28
|
+
list = Todo::List.new
|
29
|
+
list.add(name: 'do this', list: 'my todo')
|
30
|
+
assert_equal(['my todo'], list.lists)
|
31
|
+
assert_equal([], list.tasks)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_to_h
|
35
|
+
list = Todo::List.new
|
36
|
+
list.add(name: 'my task')
|
37
|
+
assert_equal(true, list.to_h.keys.include?(:tasks))
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_all_with_verbose
|
41
|
+
list = Todo::List.new
|
42
|
+
list.add(name: 'my task', priority: 'high')
|
43
|
+
assert_equal('high', list.all.first.priority)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_removing_from_internal_list
|
47
|
+
list = Todo::List.new
|
48
|
+
list.add(name: "my task")
|
49
|
+
list.remove("my task")
|
50
|
+
assert_equal([], list.all)
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_access_sub_lists
|
54
|
+
list = Todo::List.new
|
55
|
+
list.add(name: 'do this', list: 'my todo')
|
56
|
+
list.access_list('my_todo')
|
57
|
+
end
|
58
|
+
|
59
|
+
#Marking List Items as Finished
|
60
|
+
|
61
|
+
def test_finish_list_item
|
62
|
+
list = Todo::List.new
|
63
|
+
list.add(name: 'do this')
|
64
|
+
list.finish('do this')
|
65
|
+
assert_equal(true, list.tasks.first.finished?)
|
66
|
+
end
|
67
|
+
|
68
|
+
#Persistence Test
|
69
|
+
def test_saving_to_file
|
70
|
+
list = Todo::List.new(persistent: true)
|
71
|
+
list.add(name: 'do this')
|
72
|
+
list = Todo::List.load
|
73
|
+
assert_equal('do this', list.tasks.first.name)
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require_relative '../../lib/todo/presenter'
|
2
|
+
require_relative '../../lib/todo/list'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
|
5
|
+
class PresenterTest < MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
def test_presenting_list_tasks
|
8
|
+
p = Todo::Presenter.new
|
9
|
+
list = Todo::List.new
|
10
|
+
list.add(name: 'my task')
|
11
|
+
expected = "Tasks\n1. my task\n"
|
12
|
+
assert_output(expected) { p.present(item: list, info: :tasks)}
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_presenting_list_tasks_detailed
|
16
|
+
p = Todo::Presenter.new
|
17
|
+
list = Todo::List.new
|
18
|
+
list.add(name: 'my task', priority: 'high')
|
19
|
+
expected = "Tasks\n1. my task | priority: high\n"
|
20
|
+
assert_output(expected) { p.present(item: list, info: :tasks, level: :verbose)}
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_presenting_list_tasks_not_finished
|
24
|
+
p = Todo::Presenter.new
|
25
|
+
list = Todo::List.new
|
26
|
+
list.add(name: 'my task')
|
27
|
+
list.add(name: 'my other task')
|
28
|
+
list.finish('my task')
|
29
|
+
expected = "Tasks\n1. my other task\n"
|
30
|
+
assert_output(expected) {p.present(item: list, info: :tasks, exclude: :finished) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_presenting_list_tasks_not_finished_detailed
|
34
|
+
p = Todo::Presenter.new
|
35
|
+
list = Todo::List.new
|
36
|
+
list.add(name: 'my task', priority: 'high')
|
37
|
+
list.add(name: 'my other task', priority: 'high')
|
38
|
+
list.finish('my other task')
|
39
|
+
expected = "Tasks\n1. my task | priority: high\n"
|
40
|
+
assert_output(expected) { p.present(item: list, info: :tasks, level: :verbose, exclude: :finished) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_presenting_list_tasks_finished
|
44
|
+
p = Todo::Presenter.new
|
45
|
+
list = Todo::List.new
|
46
|
+
list.add(name: 'my task')
|
47
|
+
list.add(name: 'my other task')
|
48
|
+
list.finish('my task')
|
49
|
+
expected = "Tasks\n1. my task | ---- FINISHED ----\n"
|
50
|
+
assert_output(expected) { p.present(item: list, info: :tasks, level: :verbose, exclude: :open) }
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_presenting_list_lists
|
54
|
+
p = Todo::Presenter.new
|
55
|
+
list = Todo::List.new
|
56
|
+
list.add(name: 'my task', list: 'sub list')
|
57
|
+
expected = "Lists\n1. sub list\n"
|
58
|
+
assert_output(expected) { p.present(item: list, info: :lists)}
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_presenting_list_lists
|
62
|
+
p = Todo::Presenter.new
|
63
|
+
list = Todo::List.new
|
64
|
+
list.add(name: 'my task', list: 'sub list')
|
65
|
+
expected = "Lists\n1. sub list | tasks: 1\n"
|
66
|
+
assert_output(expected) { p.present(item: list, info: :lists, level: :verbose)}
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
end
|
data/test/todo_test.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require_relative '../lib/todo'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'pry'
|
4
|
+
require 'pry-debugger'
|
5
|
+
|
6
|
+
class TodoTest < MiniTest::Unit::TestCase
|
7
|
+
|
8
|
+
def teardown
|
9
|
+
file_path = File.join(Dir.home, "todo", "todo.yml")
|
10
|
+
File.delete(file_path) if File.exists?(file_path)
|
11
|
+
end
|
12
|
+
# Adding Tasks
|
13
|
+
def test_add_to_general_list_without_any_options
|
14
|
+
t = Todo::Application.new
|
15
|
+
t.add(name: "get this done")
|
16
|
+
assert_output("Tasks\n1. get this done\n") {t.tasks}
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_add_details_to_task
|
20
|
+
t = Todo::Application.new
|
21
|
+
t.add(name: "get this done", priority: "high")
|
22
|
+
assert_output("Tasks\n1. get this done | priority: high\n") {t.tasks(level: :verbose)}
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_adding_to_named_list
|
26
|
+
t = Todo::Application.new
|
27
|
+
t.add(name: "do this", list: "my todo")
|
28
|
+
assert_output("Lists\n1. my todo\n") { t.lists }
|
29
|
+
end
|
30
|
+
|
31
|
+
#Finishing Tasks
|
32
|
+
def test_finishing_task
|
33
|
+
t = Todo::Application.new
|
34
|
+
t.add(name: "do this now")
|
35
|
+
t.finish("do this now")
|
36
|
+
assert_output("Tasks\n1. do this now | ---- FINISHED ----\n") { t.tasks(level: :verbose)}
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_finishing_task_on_sublist
|
40
|
+
t = Todo::Application.new
|
41
|
+
t.add(name: "do this", list: "submarine")
|
42
|
+
t.finish("do this", list: "submarine")
|
43
|
+
assert_output("Tasks\n1. do this | ---- FINISHED ----\n") { t.tasks(level: :verbose, list: "submarine") }
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
# Removing Tasks
|
48
|
+
def test_remove_from_general_list
|
49
|
+
t = Todo::Application.new
|
50
|
+
t.add(name: "get this done")
|
51
|
+
t.remove("get this done")
|
52
|
+
assert_output("Tasks\n") { t.tasks }
|
53
|
+
end
|
54
|
+
|
55
|
+
#Persistence
|
56
|
+
def test_saving_base_list_to_file
|
57
|
+
t = Todo::Application.new(persistent: true)
|
58
|
+
t.add(name: "get this done")
|
59
|
+
t = Todo::Application.new(persistent: true)
|
60
|
+
assert_output("Tasks\n1. get this done\n") { t.tasks }
|
61
|
+
end
|
62
|
+
end
|
data/todo.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'todo/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "2do"
|
8
|
+
spec.version = Todo::VERSION
|
9
|
+
spec.authors = ["Kavinder Dhaliwal"]
|
10
|
+
spec.email = ["kavinderd@gmail.com"]
|
11
|
+
spec.summary = %q{TNT's Not a Todo}
|
12
|
+
spec.description = %q{Because if you spend all day at the terminal you might as well keep your todos there as well}
|
13
|
+
spec.homepage = "https://github.com/kavinderd/todo"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.3"
|
23
|
+
spec.add_development_dependency "pry", "~> 0.10"
|
24
|
+
spec.add_development_dependency "pry-debugger", "~>0.2"
|
25
|
+
spec.add_runtime_dependency "main", "~>6.0"
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: 2do
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kavinder Dhaliwal
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.10'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.10'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry-debugger
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.2'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: main
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '6.0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '6.0'
|
83
|
+
description: Because if you spend all day at the terminal you might as well keep your
|
84
|
+
todos there as well
|
85
|
+
email:
|
86
|
+
- kavinderd@gmail.com
|
87
|
+
executables:
|
88
|
+
- todo
|
89
|
+
extensions: []
|
90
|
+
extra_rdoc_files: []
|
91
|
+
files:
|
92
|
+
- ".gitignore"
|
93
|
+
- ".ruby-version"
|
94
|
+
- CHANGELOG
|
95
|
+
- Gemfile
|
96
|
+
- LICENSE.txt
|
97
|
+
- README.md
|
98
|
+
- Rakefile
|
99
|
+
- bin/todo
|
100
|
+
- lib/todo.rb
|
101
|
+
- lib/todo/list.rb
|
102
|
+
- lib/todo/list_item.rb
|
103
|
+
- lib/todo/presenter.rb
|
104
|
+
- lib/todo/version.rb
|
105
|
+
- test/todo/list_item_test.rb
|
106
|
+
- test/todo/list_test.rb
|
107
|
+
- test/todo/presenter_test.rb
|
108
|
+
- test/todo_test.rb
|
109
|
+
- todo.gemspec
|
110
|
+
homepage: https://github.com/kavinderd/todo
|
111
|
+
licenses:
|
112
|
+
- MIT
|
113
|
+
metadata: {}
|
114
|
+
post_install_message:
|
115
|
+
rdoc_options: []
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
requirements: []
|
129
|
+
rubyforge_project:
|
130
|
+
rubygems_version: 2.2.2
|
131
|
+
signing_key:
|
132
|
+
specification_version: 4
|
133
|
+
summary: TNT's Not a Todo
|
134
|
+
test_files:
|
135
|
+
- test/todo/list_item_test.rb
|
136
|
+
- test/todo/list_test.rb
|
137
|
+
- test/todo/presenter_test.rb
|
138
|
+
- test/todo_test.rb
|