todolist_app 1.0.0
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/lib/todolist.rb +163 -0
- data/test/todolist_test.rb +195 -0
- metadata +43 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: b7f3a095080e16013a4021af29758e915152f5038d25bc0927cf4ab6f6ffb1f7
|
|
4
|
+
data.tar.gz: 0bf89ef2a32b7393338f3132b9191fd813f4e22195161a91635a6737a8b07113
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 013a180e9fc59a2e3fbf0c266740ca42d68a02911081f7aa33f41e6e7d0ca0f8bb11cc81dfdd930cfc54128508a30f89880ded435c1d6daf506641dc2ed05398
|
|
7
|
+
data.tar.gz: 89b5c94545d30d5daf08afdac310f0ef68178bc307bca0ffbcbda1f1eb71fe98538285bc81252c5c9389a944ee98b57e4cd9445d083fbb8bc5f1691fa3ce7193
|
data/lib/todolist.rb
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# This class represents a todo item and its associated
|
|
2
|
+
# data: name and description. There's also a "done"
|
|
3
|
+
# flag to show whether this todo item is done.
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'stamp'
|
|
6
|
+
|
|
7
|
+
class Todo
|
|
8
|
+
DONE_MARKER = 'X'
|
|
9
|
+
UNDONE_MARKER = ' '
|
|
10
|
+
|
|
11
|
+
attr_accessor :title, :description, :done, :due_date
|
|
12
|
+
|
|
13
|
+
def initialize(title, due_date=nil, description='')
|
|
14
|
+
@title = title
|
|
15
|
+
@description = description
|
|
16
|
+
@done = false
|
|
17
|
+
@due_date = due_date
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def done!
|
|
21
|
+
self.done = true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def done?
|
|
25
|
+
done
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def undone!
|
|
29
|
+
self.done = false
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def to_s
|
|
33
|
+
result = "[#{done? ? DONE_MARKER : UNDONE_MARKER}] #{title}"
|
|
34
|
+
result += due_date.stamp(' (Due: Friday January 6)') if due_date
|
|
35
|
+
result
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def ==(otherTodo)
|
|
39
|
+
title == otherTodo.title &&
|
|
40
|
+
description == otherTodo.description &&
|
|
41
|
+
done == otherTodo.done
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# This class represents a collection of Todo objects.
|
|
46
|
+
# You can perform typical collection-oriented actions
|
|
47
|
+
# on a TodoList object, including iteration and selection.
|
|
48
|
+
|
|
49
|
+
class TodoList
|
|
50
|
+
attr_accessor :title
|
|
51
|
+
|
|
52
|
+
def initialize(title)
|
|
53
|
+
@title = title
|
|
54
|
+
@todos = []
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def size
|
|
58
|
+
@todos.size
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def first
|
|
62
|
+
@todos.first
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def last
|
|
66
|
+
@todos.last
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def shift
|
|
70
|
+
@todos.shift
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def pop
|
|
74
|
+
@todos.pop
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def done?
|
|
78
|
+
@todos.all? { |todo| todo.done? }
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def <<(todo)
|
|
82
|
+
raise TypeError, 'can only add Todo objects' unless todo.instance_of? Todo
|
|
83
|
+
|
|
84
|
+
@todos << todo
|
|
85
|
+
end
|
|
86
|
+
alias_method :add, :<<
|
|
87
|
+
|
|
88
|
+
def item_at(idx)
|
|
89
|
+
@todos.fetch(idx)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def mark_done_at(idx)
|
|
93
|
+
item_at(idx).done!
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def mark_undone_at(idx)
|
|
97
|
+
item_at(idx).undone!
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def done!
|
|
101
|
+
@todos.each_index do |idx|
|
|
102
|
+
mark_done_at(idx)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def remove_at(idx)
|
|
107
|
+
@todos.delete(item_at(idx))
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def to_s
|
|
111
|
+
text = "---- #{title} ----\n"
|
|
112
|
+
text << @todos.map(&:to_s).join("\n")
|
|
113
|
+
text
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def to_a
|
|
117
|
+
@todos.clone
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def each
|
|
121
|
+
@todos.each do |todo|
|
|
122
|
+
yield(todo)
|
|
123
|
+
end
|
|
124
|
+
self
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def select
|
|
128
|
+
list = TodoList.new(title)
|
|
129
|
+
each do |todo|
|
|
130
|
+
list.add(todo) if yield(todo)
|
|
131
|
+
end
|
|
132
|
+
list
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# returns first Todo by title, or nil if no match
|
|
136
|
+
def find_by_title(title)
|
|
137
|
+
select { |todo| todo.title == title }.first
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def all_done?
|
|
141
|
+
select { |todo| todo.done? }
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def all_not_done?
|
|
145
|
+
select { |todo| !todo.done? }
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def mark_done(title)
|
|
149
|
+
find_by_title(title) && find_by_title(title).done!
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def mark_all_done
|
|
153
|
+
each { |todo| todo.done! }
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def mark_all_undone
|
|
157
|
+
each { |todo| todo.undone! }
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def clear
|
|
161
|
+
@todos = []
|
|
162
|
+
end
|
|
163
|
+
end
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
require 'bundler/setup'
|
|
2
|
+
require 'minitest/autorun'
|
|
3
|
+
require 'minitest/reporters'
|
|
4
|
+
require 'date'
|
|
5
|
+
require_relative '../lib/todolist'
|
|
6
|
+
|
|
7
|
+
Minitest::Reporters.use!
|
|
8
|
+
|
|
9
|
+
class TodoListTest < Minitest::Test
|
|
10
|
+
|
|
11
|
+
def setup
|
|
12
|
+
@todo1 = Todo.new("Buy milk")
|
|
13
|
+
@todo2 = Todo.new("Clean room")
|
|
14
|
+
@todo3 = Todo.new("Go to gym")
|
|
15
|
+
@todos = [@todo1, @todo2, @todo3]
|
|
16
|
+
|
|
17
|
+
@list = TodoList.new("Today's Todos")
|
|
18
|
+
@list.add(@todo1)
|
|
19
|
+
@list.add(@todo2)
|
|
20
|
+
@list.add(@todo3)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_to_a
|
|
24
|
+
assert_equal(@todos, @list.to_a)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_size
|
|
28
|
+
assert_equal(@list.size, @todos.size)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_first
|
|
32
|
+
assert_equal(@list.first, @todos.first)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def test_last
|
|
36
|
+
assert_equal(@list.last, @todos.last)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_shift
|
|
40
|
+
assert_equal(@list.shift, @todos.first)
|
|
41
|
+
assert_equal(@list.size, @todos.size - 1)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_pop
|
|
45
|
+
assert_equal(@list.pop, @todos.last)
|
|
46
|
+
assert_equal(@list.size, @todos.size - 1)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_done_question
|
|
50
|
+
assert_equal(false, @list.done?)
|
|
51
|
+
@list.done!
|
|
52
|
+
assert_equal(true, @list.done?)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def test_add_raise_error
|
|
56
|
+
assert_raises(TypeError) { @list.add(1) }
|
|
57
|
+
assert_raises(TypeError) { @list.add("Hello") }
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_shovel_operator
|
|
61
|
+
assert_equal(@list.size, @todos.size)
|
|
62
|
+
@list << Todo.new('Do dishes')
|
|
63
|
+
assert_equal(@list.size, @todos.size + 1)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def test_add_alias
|
|
67
|
+
assert_equal(@list.size, @todos.size)
|
|
68
|
+
@list.add Todo.new('Do dishes')
|
|
69
|
+
assert_equal(@list.size, @todos.size + 1)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def test_item_at
|
|
73
|
+
assert_equal(@list.item_at(0), @todos.first)
|
|
74
|
+
assert_equal(@list.item_at(2), @todos.last)
|
|
75
|
+
assert_raises(IndexError) { @list.item_at(3) }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def test_mark_done_at
|
|
79
|
+
assert_raises(IndexError) { @list.mark_done_at(3) }
|
|
80
|
+
assert_raises(IndexError) { @list.mark_done_at(100) }
|
|
81
|
+
|
|
82
|
+
@list.mark_done_at(0)
|
|
83
|
+
assert(@todos.first.done?)
|
|
84
|
+
@list.mark_done_at(1)
|
|
85
|
+
assert(@todos[1].done?)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def test_mark_undone_at
|
|
89
|
+
@list.done!
|
|
90
|
+
assert_equal(@todos.first.done?, true)
|
|
91
|
+
|
|
92
|
+
@list.mark_undone_at(0)
|
|
93
|
+
assert_equal(@todos.first.done?, false)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def test_done_bang
|
|
97
|
+
assert_equal(@todos[0].done?, false)
|
|
98
|
+
assert_equal(@todos[1].done?, false)
|
|
99
|
+
assert_equal(@todos[2].done?, false)
|
|
100
|
+
@list.done!
|
|
101
|
+
assert(@todos[0].done?)
|
|
102
|
+
assert(@todos[1].done?)
|
|
103
|
+
assert(@todos[2].done?)
|
|
104
|
+
assert(@list.done?)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def test_remove_at
|
|
108
|
+
assert_raises(IndexError) { @list.remove_at(100) }
|
|
109
|
+
|
|
110
|
+
assert_equal(3, @list.size)
|
|
111
|
+
@list.remove_at(1)
|
|
112
|
+
assert_equal([@todos[0], @todos[2]], @list.to_a)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def test_to_s
|
|
116
|
+
@todo2.due_date = Date.civil(2021, 11, 6)
|
|
117
|
+
output = <<~OUTPUT.chomp
|
|
118
|
+
---- Today's Todos ----
|
|
119
|
+
[ ] Buy milk
|
|
120
|
+
[ ] Clean room (Due: Saturday November 6)
|
|
121
|
+
[ ] Go to gym
|
|
122
|
+
OUTPUT
|
|
123
|
+
assert_equal(output, @list.to_s)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def test_to_s_again
|
|
127
|
+
@list.mark_done_at(0)
|
|
128
|
+
output = <<~OUTPUT.chomp
|
|
129
|
+
---- Today's Todos ----
|
|
130
|
+
[X] Buy milk
|
|
131
|
+
[ ] Clean room
|
|
132
|
+
[ ] Go to gym
|
|
133
|
+
OUTPUT
|
|
134
|
+
|
|
135
|
+
assert_equal(output, @list.to_s)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def test_to_s_all_marked
|
|
139
|
+
@list.done!
|
|
140
|
+
output = <<~OUTPUT.chomp
|
|
141
|
+
---- Today's Todos ----
|
|
142
|
+
[X] Buy milk
|
|
143
|
+
[X] Clean room
|
|
144
|
+
[X] Go to gym
|
|
145
|
+
OUTPUT
|
|
146
|
+
assert_equal(output, @list.to_s)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def test_each
|
|
150
|
+
result = []
|
|
151
|
+
@list.each { |todo| result << todo }
|
|
152
|
+
assert_equal([@todo1, @todo2, @todo3], result)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def test_each_returns_self
|
|
156
|
+
list = @list.each { |todo| }
|
|
157
|
+
assert_equal(list, @list)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def test_select
|
|
161
|
+
@todo1.done!
|
|
162
|
+
list = TodoList.new(@list.title)
|
|
163
|
+
list.add(@todo1)
|
|
164
|
+
|
|
165
|
+
assert_equal(list.title, @list.title)
|
|
166
|
+
assert_equal(list.to_s, @list.select{ |todo| todo.done? }.to_s)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def test_all_not_done
|
|
170
|
+
@list.mark_all_done
|
|
171
|
+
assert(@list.done?)
|
|
172
|
+
@list.mark_all_undone
|
|
173
|
+
assert(@list.all_not_done?)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def test_mark_done_by_title
|
|
177
|
+
@list.mark_done(@todo1.title)
|
|
178
|
+
assert(@list.first.done?)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def test_mark_all_done
|
|
182
|
+
@list.mark_all_done
|
|
183
|
+
assert(@list.all_done?)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def test_no_due_date
|
|
187
|
+
assert_nil(@todo1.due_date)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def test_due_date
|
|
191
|
+
due_date = Date.today + 3
|
|
192
|
+
@todo1.due_date = due_date
|
|
193
|
+
assert_equal(due_date, @todo1.due_date)
|
|
194
|
+
end
|
|
195
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: todolist_app
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Cameron Augustine
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2021-11-04 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: This is a simple todo list manager!
|
|
14
|
+
email: mtcameron5@gmail.com
|
|
15
|
+
executables: []
|
|
16
|
+
extensions: []
|
|
17
|
+
extra_rdoc_files: []
|
|
18
|
+
files:
|
|
19
|
+
- lib/todolist.rb
|
|
20
|
+
- test/todolist_test.rb
|
|
21
|
+
homepage: https://github.com/mtcameron5/todolist_app_ruby
|
|
22
|
+
licenses: []
|
|
23
|
+
metadata: {}
|
|
24
|
+
post_install_message:
|
|
25
|
+
rdoc_options: []
|
|
26
|
+
require_paths:
|
|
27
|
+
- lib
|
|
28
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
34
|
+
requirements:
|
|
35
|
+
- - ">="
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
37
|
+
version: '0'
|
|
38
|
+
requirements: []
|
|
39
|
+
rubygems_version: 3.2.30
|
|
40
|
+
signing_key:
|
|
41
|
+
specification_version: 4
|
|
42
|
+
summary: Todo List Manager!
|
|
43
|
+
test_files: []
|