Skip to content

Instantly share code, notes, and snippets.

@tannerwelsh
Created July 12, 2012 21:08
Show Gist options
  • Select an option

  • Save tannerwelsh/3101022 to your computer and use it in GitHub Desktop.

Select an option

Save tannerwelsh/3101022 to your computer and use it in GitHub Desktop.
Tanner's solution to the Week 4 Ruby Assessment
# DBC Week 4 Ruby Assessment
# Tanner Welsh
# ____________
######################################################################################
### PART 1 : OO Design ###############################################################
# module AddressBook
#
# class Person
# # Name should user-writable. Writing other attributes
# # to be controlled by specific methods below.
# attr_writer :name
# attr_reader :emails, :phones, :addresses
#
# def initialize(name, opts = {})
# # Instantiate with name and optional hash of attributes
# end
#
# def add_email(email)
# # Insert new email into hash of emails
# end
#
# def add_phone(phone)
# # Insert new phone number into hash of phone numbers
# end
#
# def add_address(address)
# # Create new address object and insert into hash of addresses
# end
#
# def to_s
# # Output object into human-readable format
# end
# end
#
# class Address
# # All attributes should be user-editable
# attr_accessor :category, :street, :city, :state, :zip
#
# def initialize(category, street, city, state, zip)
# # Instantiate with 4 req'd parameters
# end
#
# def to_s
# # Output address into human-readable format
# end
#
# def self.from_string(string)
# # Parse address string into component attributes and create new address object
# end
# end
#
# end
######################################################################################
### PART 2: TDD ######################################################################
require 'rspec'
require 'simplecov'
SimpleCov.start
module AddressBook
class Person
# Name should user-editable. Writing other attributes
# to be controlled by specific methods below.
attr_accessor :name
attr_reader :emails, :phones, :addresses
def initialize(name, opts = {})
# Instantiate with name and optional hash of attributes
@name = name
@phones = opts.fetch(:phone) { Hash.new }
@emails = opts.fetch(:email) { Hash.new }
@addresses = opts.fetch(:address) { Array.new }
end
def add_email(email)
# Insert new email into hash of emails
@emails.merge!(email)
end
def add_phone(phone)
# Insert new phone number into hash of phone numbers
@phones.merge!(phone)
end
def add_address(address)
# Create new address object and insert into hash of addresses
@addresses << address
end
def print_addresses
# Print out a nice list of addresses
@addresses.map { |addy| addy.to_s }
end
end
class Address
# All attributes should be user-editable
attr_accessor :street, :city, :state, :zip
def initialize(street, city, state, zip)
# Instantiate with 4 req'd parameters
end
def to_s
# Output address into human-readable format
end
end
end
# Hack so that simplecov works in same file:
# require './twelsh_week4_ruby_solution.rb'
# There must be a better solution out there somewhere...
describe AddressBook::Person do
before :each do
@person = AddressBook::Person.new("Joe Schmo")
end
context ".new" do
it "creates an instance of the Person class" do
@person.should be_an_instance_of AddressBook::Person
end
it "instantiates a new object with the proper attributes" do
@person.name.should eq "Joe Schmo"
[@person.phones, @person.emails, @person.addresses].each do |attr|
attr.should be_empty
end
end
end
context "#name=" do
it "changes the name" do
@person.name = "Tom Jones"
@person.name.should eq "Tom Jones"
end
end
context "#add_email=" do
it "adds an email" do
lambda { @person.add_email(:school => 'joe@schmo.edu') }.
should change(@person.emails, :length).from(0).to(1)
end
end
context "#add_phone=" do
it "adds a phone number" do
lambda { @person.add_phone(:mobile => '981-127-4713') }.
should change(@person.phones, :length).from(0).to(1)
end
end
describe "getter methods" do
context "#phones" do
it "retrieves the phone numbers" do
@phone = {:home => '123-518-3182'}
@person.add_phone(@phone)
@person.phones[:home].should eq @phone[:home]
end
end
context "#emails" do
it "retrieves the email addresses" do
@email = {:work => 'joe@schmo.co'}
@person.add_email(@email)
@person.emails[:work].should eq @email[:work]
end
end
end
describe "addresses" do
# Sample data to work with
SAMPLES = [ 'home, 123 Oak Ln, Belvedere, OK 12391',
'work, 912 Moonshine Dr, Bourbon, TN 34518' ]
let (:populate_addresses) do
[@home, @work].each_with_index do |addy, i|
addy = mock(AddressBook::Address)
addy.stub(:to_s).and_return(SAMPLES[i])
@person.add_address(addy)
end
end
context "#add_address" do
it "adds address to person" do
@person.addresses.should be_empty
populate_addresses
@person.addresses.length.should be 2
end
end
context "#print_addresses" do
it "prints a list of addresses" do
populate_addresses
@person.print_addresses.should eq SAMPLES
end
end
end
end
######################################################################################
### PART 3: Schema Design ############################################################
# persons
# -------
# id (primary key)
# name
#
# emails
# ------
# id (primary key)
# person_id (foreign key)
# text
#
# phones
# ------
# id (primary key)
# person_id (foreign key)
# number
#
# addresses
# ---------
# id (primary key)
# person_id (foreign key)
# street
# city
# state
# zip
######################################################################################
### PART 4: SQL ######################################################################
# Give a query to return all addresses for a user whose name is Barack Obama.
# SQL>
# SELECT * FROM addresses
# INNER JOIN persons
# ON addresses.person_id = person.id
# WHERE person.name = 'Barack Obama';
# Give a query to return all users who have addresses in California.
# SQL>
# SELECT * FROM persons
# INNER JOIN addresses
# ON persons.id = addresses.person_id
# WHERE addresses.state LIKE 'CA' OR addresses.state = 'California';
# Give a query to add the following address to the user Barack Obama: 717 California Street, San Francisco CA, 94108
# SQL>
# INSERT INTO addresses
# VALUES ('717 California Street', 'San Francisco', 'CA', '94108')
# WHERE addresses.person_id = persons.id AND
# persons.name = 'Barack Obama';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment