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.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/lib/todolist.rb +163 -0
  3. data/test/todolist_test.rb +195 -0
  4. 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: []