Skip to content

Instantly share code, notes, and snippets.

@istro
Created June 28, 2012 04:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save istro/3008991 to your computer and use it in GitHub Desktop.
Save istro/3008991 to your computer and use it in GitHub Desktop.
Todo CLI with rspec
module Todo
class List
def initialize(file_path)
@file_path = file_path
@tasks = parse_tasks(File.read(@file_path))
end
def parse_tasks(text)
# we use #collect here so that we will return an array of tasks
text.split("\n").collect do |line|
Task.from_string(line.split[1..-1].join(' '))
end
end
def print_tasks(options)
case options[:status]
when :incomplete
# choose only the tasks that are incomplete
# in long form this would look like:
# tasks = @tasks.select { |task| task.incomplete? }
tasks = @tasks.select(&:incomplete?)
when :complete
tasks = @tasks.select(&:complete?)
else
# if we're not passed either of the above print options, we'll print them all
tasks = @tasks
end
# task_strings accepts a block and yields a formatted string for each task
task_strings(tasks) { |string| print string }
end
def add_task(title)
@tasks << Task.new(title)
write_tasks
end
def delete_task(index)
@tasks.delete_at(index-1)
write_tasks
end
def complete_task(index)
@tasks[index-1].complete!
write_tasks
end
private
def write_tasks
File.open(@file_path, 'w') do |file|
# using the task_strings method again, this time to write the strings to a file
task_strings { |string| file.write(string) }
end
end
def task_strings(tasks=nil)
tasks ||= @tasks
tasks.each_with_index do |task, index|
yield "#{index+1}. #{task}\n"
end
end
end
end
require 'simplecov'
require 'rspec'
SimpleCov.start
require './list.rb'
include Todo
# List.new
describe "#List.new" do
before (:each) do
@list = List.new("todo.txt")
end
it "initializes a list from a file" do
@list.should be_an_instance_of List
end
it "properly parses a list from a file" do
@list.print_tasks({}).length.should eq 3
end
end
# list.add_task
describe "#add_tasks" do
it "adds a task" do
@list = List.new("todo.txt")
@list.add_task("new task")
@list.print_tasks({}).last.to_s.index("new task").should_not be_nil
end
end
# list.delete_task
describe "delete_task" do
it "deltes a task" do
@list = List.new("todo.txt")
@list.print_tasks({}).last.to_s.index("new task").should_not be_nil
@list.delete_task(4)
@list.print_tasks({}).last.to_s.index("new task").should be_nil
end
end
# list.complete_task
describe "complete_task" do
it "completes a task" do
@list = List.new("todo.txt")
@list.print_tasks({}).last.to_s.split(";").last.strip.should be_empty
@list.complete_task(3)
@list.print_tasks({}).last.to_s.split(";").last.strip.should_not be_empty
end
end
# list.print_tasks
describe "#print_tasks" do
before(:each) do
@list = List.new("todo.txt")
end
it "prints all tasks" do
@list.print_tasks({}).length.should eq 3
end
it "prints completed tasks" do
@list.print_tasks({:status => :complete}).length.should eq 1
end
it "prints all incomplete tasks" do
@list.print_tasks({:status => :incomplete}).length.should eq 2
end
end
# so that we can use Time.parse()
require 'time'
module Todo
class Task
def initialize(title, created_at=Time.now, completed_at=nil)
@title = title
@created_at = created_at
@completed_at = completed_at
end
# a factory method on Task to parse a string and return a new task
def self.from_string(string)
# we expect a string in a format like this:
# "eat food ; 2012-06-25 23:18:31 -0700 ; 2012-06-25 23:18:31 -0700"
# so we split it on ';' and strip out any extra spaces on the ends
array = string.split(';').collect(&:strip)
title = array[0]
# if created_at is blank then we want to set it to now
created_at = array[1].nil? ? Time.now : Time.parse(array[1])
# let completed_at be nil if it's blank
completed_at = Time.parse(array[2]) unless array[2].nil?
# this initializes and returns a new instance of Task
self.new(title, created_at, completed_at)
end
def to_s
# you don't need to use {} when you're interpolating instance variables
"#@title ; #@created_at ; #@completed_at"
end
def complete!
@completed_at = Time.now
end
def complete?
!incomplete?
end
def incomplete?
@completed_at.nil?
end
end
end
require 'simplecov'
require 'rspec'
SimpleCov.start
require './task.rb'
include Todo
#Task.new
describe "Task.new" do
before (:each) do
@task = Task.new("do the laundry")
end
it "initializes a task correctly" do
@task.should be_an_instance_of Task
end
it "remembers the title it was initialized with" do
@task.to_s.index("do the laundry").should not be_nil
end
it "initializes the created date"
it "initializes the completed date"
end
# Task.from_string
describe "#self.from_string" do
it "initializes from a string" do
task = Task.from_string("eat food ; 2012-06-25 23:18:31 -0700 ; 2012-06-25 23:18:31 -0700")
task.to_s.should eq "eat food ; 2012-06-25 23:18:31 -0700 ; 2012-06-25 23:18:31 -0700"
end
it "initializes with a blank created at"
it "initializes with a blank completed at"
end
#task.to_s
describe "#to_s" do
it "prints out the title, date created and date completed" do
date_created = Time.now.advance({:months => -1})
date_completed = Time.now
task = Task.new("Hello there", date_created, date_completed)
task.to_s. should eq "hello there ; #{date_created} ; #{date_completed}"
end
end
# task.complete!
# task.complete?
# task.incomplete
describe "completeness stuff"
before (:each) do
@task = Task.new("do the laundry")
end
it "is complete when initialized" do
@task.complete?.should_not be_true
@task.incomplete?.should be_true
end
it "is complete when I complete it" do
@task.complete!
@task.complete?.should be_true
@task.incomplete?.should_not be_true
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment