mmtodo 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (C) 2012 Mike Mitrovich
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,3 @@
1
+ A simple command line todo app.
2
+ Created to help me learn some ruby concepts.
3
+
@@ -0,0 +1,8 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require_relative '../lib/mm_todo/todo_app.rb'
4
+
5
+
6
+ myapp = MMToDo::ToDoApp.instance
7
+
8
+ myapp.start# ["test"]
@@ -0,0 +1,97 @@
1
+ require 'singleton'
2
+ require_relative 'todo_list'
3
+
4
+ module MMToDo
5
+ class ToDoApp
6
+ include Singleton
7
+
8
+ attr_reader :file
9
+
10
+ def start (params=ARGV, dest = STDOUT)
11
+ check_params(params,dest)
12
+ @file = params.shift
13
+ @list = ToDoList.new @file
14
+ #@list.load if File.exist? File.join(File.dirname(__FILE__), '\..\bin\\' + @file + '.save')
15
+ @list.load if File.exist? File.join(File.expand_path("../../bin/", File.dirname(__FILE__)), @file + '.save')
16
+ @status = :menu
17
+ app_loop()
18
+ end
19
+
20
+ def check_params(params, dest)
21
+ unless params.size == 1
22
+ puts "Wrong number of arguments."
23
+ puts "Usage: ruby todo.rb list_name\n"
24
+ exit
25
+ end
26
+ end
27
+
28
+ def app_loop
29
+ while @status != :quit
30
+ case @input
31
+ when "q","Q"
32
+ @status = :quit
33
+ when "a", "A"
34
+ add_item
35
+ when "d", "D"
36
+ mark_done
37
+ when "p", "P"
38
+ purge_done
39
+ else
40
+ main_menu
41
+ end
42
+ end
43
+ end
44
+
45
+ def main_menu
46
+ @list.show_all
47
+ puts @error
48
+ @error = nil
49
+ puts "[Commands: q=quit, a=add, d=mark done, p=purge done items]"
50
+ @input = $stdin.gets.chomp
51
+ end
52
+
53
+ def add_item
54
+ @input.clear
55
+ puts "Description (leave blank to cancel):"
56
+ desc = $stdin.gets.chomp
57
+ @list.add desc
58
+ @error = "(Added: #{desc})"
59
+ end
60
+
61
+ def mark_done
62
+ @input.clear
63
+ puts "Which number?"
64
+ selection = $stdin.gets.chomp
65
+ check_selection(selection)
66
+ end
67
+
68
+ def check_selection(selection)
69
+ if selection !~ /^\d+$/
70
+ @error = "[Invalid selection] Just the number, please."
71
+ return
72
+ elsif selection.to_i == 0 || selection.to_i > @list.size
73
+ @error = "[Invalid selection] No todo with that number."
74
+ return
75
+ end
76
+
77
+ index = selection.to_i
78
+ @error = "(Item completed: #{@list.select(index)})"
79
+ @list.select(index).do
80
+ end
81
+
82
+ def purge_done
83
+ @input.clear
84
+ puts "Are you sure?(y/n)"
85
+ answer = $stdin.gets.chomp
86
+ case answer
87
+ when "y", "Y"
88
+ @list.purge_done
89
+ @error = "(Done items purged)"
90
+ else
91
+ @error = "(purge cancelled)"
92
+ end
93
+ end
94
+
95
+ end
96
+ end
97
+
@@ -0,0 +1,18 @@
1
+
2
+ module MMToDo
3
+ class ToDoItem
4
+
5
+ def initialize(desc, parent)
6
+ @description = desc
7
+ @parent_list = parent
8
+ end
9
+
10
+ def to_s
11
+ return @description
12
+ end
13
+
14
+ def do
15
+ @parent_list.mark_done(self)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,94 @@
1
+ require_relative 'todo_item'
2
+
3
+
4
+ module MMToDo
5
+
6
+ class ToDoList
7
+ def initialize(save_file="unnamed")
8
+ @list = []
9
+ @done = []
10
+ #@save_file = File.join(File.dirname(__FILE__), '\..\bin\\' + @save_file + '.save')
11
+ @save_file = File.join(File.expand_path("../../bin/", File.dirname(__FILE__)), save_file + '.save')
12
+ end
13
+
14
+ def save
15
+ File.open(@save_file, 'w') {|f| f.write Marshal.dump([@list,@done]) }
16
+ end
17
+
18
+ def load
19
+ @list,@done = Marshal.load(File.read(@save_file))
20
+ end
21
+
22
+ def add(todo = "")
23
+ raise if todo =~ /^\s*$/
24
+ @list.push ToDoItem.new(todo, self)
25
+ save
26
+ rescue
27
+ puts "[Empty todo not added...]"
28
+ end
29
+
30
+ def size
31
+ return @list.size
32
+ end
33
+
34
+ def empty?
35
+ return @list.empty?
36
+ end
37
+
38
+ def show_todos(dest = STDOUT)
39
+ @list.each_index {|index| dest.puts "#{index + 1}. #{@list[index]}"}
40
+ end
41
+
42
+ def show_done(dest = STDOUT)
43
+ @done.each {|item| dest.puts item}
44
+ end
45
+
46
+ def select(index)
47
+ return @list[index - 1]
48
+ end
49
+
50
+ def mark_done(item)
51
+ @done.push item
52
+ @list.delete item
53
+ save
54
+ end
55
+
56
+ def show_all(dest = STDOUT)
57
+ puts "TODO:"
58
+ puts "=========="
59
+ show_todos
60
+ puts "\n\nDone:"
61
+ puts "=========="
62
+ show_done
63
+ puts "\n\n\n"
64
+ end
65
+
66
+ def purge_done
67
+ @done = []
68
+ save
69
+ end
70
+ end
71
+ end
72
+
73
+ if __FILE__ == $0
74
+ mylist = ToDoList.new
75
+
76
+ mylist.add("feed the fish")
77
+ mylist.add("go shopping")
78
+ mylist.add("wash dishes")
79
+ mylist.add " "
80
+
81
+ mylist.select(2).do
82
+
83
+ mylist.show_all
84
+
85
+ mylist.purge_done
86
+ mylist.show_all
87
+
88
+ File.open('mylist.save', 'w') {|f| f.write Marshal.dump(mylist) }
89
+
90
+ newlist = Marshal.load File.read('mylist.save')
91
+
92
+ puts "Newlist:"
93
+ newlist.show_all
94
+ end
@@ -0,0 +1,24 @@
1
+ require_relative '../lib/todo_app'
2
+ require 'stringio'
3
+
4
+ describe ToDoApp do
5
+ before do
6
+ @output = StringIO.new
7
+ @myapp = ToDoApp.instance
8
+ end
9
+
10
+ it "displays some help text if no commandline parameter given" do
11
+ @myapp.start([], @output)
12
+ @output.rewind
13
+ @output.read.should match /ToDoApp: Wrong number of parameters/
14
+ end
15
+
16
+ it "displays some help text if more than 1 commandline parameter given" do
17
+ @myapp.start(["item1", "item2"], @output)
18
+ @output.rewind
19
+ @output.read.should match /ToDoApp: Wrong number of parameters/
20
+ end
21
+
22
+
23
+
24
+ end
@@ -0,0 +1,155 @@
1
+ require_relative '../lib/todo_list'
2
+ require_relative '../lib/todo_item'
3
+ require 'stringio'
4
+
5
+ describe ToDoList do
6
+ before do
7
+ @output = StringIO.new
8
+ @mylist = ToDoList.new
9
+ @wash_dishes = "wash the dishes"
10
+ @trash = "take out the trash"
11
+ end
12
+
13
+ it "starts with a list of 0" do
14
+ @mylist.size.should be 0
15
+ end
16
+
17
+ it "ititializes to empty" do
18
+ @mylist.should be_empty
19
+ end
20
+
21
+ it "does not add a todo composed of only whitespace" do
22
+ @mylist.add @wash_dishes
23
+ @mylist.add ""
24
+ @mylist.add " "
25
+ @mylist.size.should == 1
26
+ end
27
+
28
+ context "with one todo added" do
29
+ before do
30
+ @mylist.add(@wash_dishes)
31
+ end
32
+ it "has a size of 1" do
33
+ @mylist.size.should be 1
34
+ end
35
+
36
+ it "reports that it is no longer empty" do
37
+ @mylist.should_not be_empty
38
+ end
39
+ end
40
+
41
+ context "with two todos added" do
42
+ it "has a size of 2" do
43
+ @mylist.add(@wash_dishes)
44
+ @mylist.add(@trash)
45
+ @mylist.size.should be 2
46
+ end
47
+ end
48
+ context "with a populated list" do
49
+ before do
50
+ @mylist.add "Wash the dog"
51
+ @mylist.add "Clean the table"
52
+ @mylist.add "Clean bathroom"
53
+ end
54
+
55
+ it "lists the current todo items" do
56
+ @mylist.show_todos(@output)
57
+ @output.seek(0)
58
+ @output.read.should match /1\. Wash the dog/
59
+ end
60
+
61
+ it "lets todos be selected by index" do
62
+ @output.print @mylist.select(2)
63
+ @output.seek 0
64
+ @output.read.should == "Clean the table"
65
+ end
66
+
67
+ it "tracks items that are done" do
68
+ @mylist.select(2).do
69
+ @mylist.show_done(@output)
70
+ @output.seek 0
71
+ @output.read.should == "Clean the table\n"
72
+ end
73
+
74
+ it "allows done items to be purged" do
75
+ @mylist.select(2).do
76
+ @mylist.purge_done
77
+ @mylist.show_done(@output)
78
+ @output.seek 0
79
+ @output.read.should == ""
80
+ end
81
+
82
+
83
+ end
84
+ context "saving / loading" do
85
+ before do
86
+ @savetest = ToDoList.new("savetest")
87
+ @list1 = ToDoList.new("list1")
88
+ @todo1 = "go to work"
89
+ @todo2 = "pay bills"
90
+ @todo3 = "feed dog"
91
+ end
92
+
93
+ after do
94
+ files = ["savetest.save", "list1.save", "testlist.save", "unnamed.save"]
95
+ files.each do |file|
96
+ File.delete file if File.exist? file
97
+ end
98
+ end
99
+
100
+ it "initializes a save file" do
101
+ @savetest.save
102
+ File.exist?("savetest.save").should be_true
103
+ File.delete("savetest.save")
104
+ end
105
+
106
+ it "loads saved lists" do@list1.add @todo1
107
+ @list1.add @todo2
108
+ @list1.add @todo3
109
+ @list1.select(2).do
110
+ @list1.save
111
+
112
+ list2 = ToDoList.new("list1")
113
+ list2.load
114
+ list2.show_done(@output)
115
+ @output.rewind
116
+ @output.read.should == "pay bills\n"
117
+ end
118
+ it "updates the save file when adding new todos" do
119
+ @savetest.add @todo1
120
+
121
+ newlist = ToDoList.new("savetest")
122
+ newlist.load
123
+ newlist.show_todos(@output)
124
+ @output.rewind
125
+ @output.read.should == "1. go to work\n"
126
+ end
127
+
128
+ it "updates the save file when marking items done" do
129
+ @savetest.add @todo1
130
+ @savetest.add @todo2
131
+
132
+ @savetest.select(2).do
133
+
134
+ newlist = ToDoList.new("savetest")
135
+ newlist.load
136
+ newlist.show_done(@output)
137
+ @output.rewind
138
+ @output.read.should == "pay bills\n"
139
+ end
140
+
141
+ it "updates the save file when purging done items" do
142
+ @savetest.add @todo1
143
+ @savetest.add @todo2
144
+
145
+ @savetest.select(2).do
146
+ @savetest.purge_done
147
+
148
+ newlist = ToDoList.new("savetest")
149
+ newlist.load
150
+ newlist.show_done(@output)
151
+ @output.rewind
152
+ @output.read.should == ""
153
+ end
154
+ end # save/load context
155
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mmtodo
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mike Mitrovich
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: ! 'A simple command line todo app.
31
+
32
+ Created to help me learn some ruby concepts.
33
+
34
+
35
+ '
36
+ email: mmitrovich@gmail.com
37
+ executables:
38
+ - mmtodo
39
+ extensions: []
40
+ extra_rdoc_files: []
41
+ files:
42
+ - bin/mmtodo
43
+ - lib/mm_todo/todo_app.rb
44
+ - lib/mm_todo/todo_item.rb
45
+ - lib/mm_todo/todo_list.rb
46
+ - spec/mm_todo/todo_app_spec.rb
47
+ - spec/mm_todo/todo_list_spec.rb
48
+ - LICENSE
49
+ - README
50
+ homepage:
51
+ licenses: []
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '1.9'
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubyforge_project:
70
+ rubygems_version: 1.8.24
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: A simple commandline based todo app to teach myself some ruby concepts
74
+ test_files:
75
+ - spec/mm_todo/todo_app_spec.rb
76
+ - spec/mm_todo/todo_list_spec.rb