Exercises

Exercise-1-1
# Exercise:  Take this file and add some RSS parsing to it.
# Perhaps revealing which items are new since the last time you checked.

require 'open-uri'

url = 'http://scoops.totallyrule.com/xml/rss/feed.xml' # pick an rss feed to track
lastfile = 'lastmod.log' # file to save/retrieve the time we checked

# let's check to see when we last hit this feed
lastcheck = File.open(lastfile, 'r').read.chomp

# now convert the time to a Time object with the correct net standard
lastcheck = Time.parse(lastcheck).rfc2822

begin

  # we're passing in a simple hash to apply our header
  # If-Modified-Since will compare our time to the modified time of the file
  # on the server and if it's newer than lastcheck it will give us the feed
  # otherwise we get nothing and the rescue part kicks in

  open(url, { 'If-Modified-Since' => lastcheck }) do |feed|
    puts "The feed has changed.\n"

    # Try something more interesting here with the rss module
    # Tutorial: http://www.cozmixng.org/~rwiki/?cmd=view;name=RSS+Parser%3A%3ATutorial.en
  end

rescue OpenURI::HTTPError # the exception open-uri throws on http errors
  puts "No file available or file has not changed.\n"
ensure

  # save the time of this check
  # this part happens good or bad

  File.open(lastfile, 'w') do |f|
    f.write(Time.now.to_s + "\n")
  end
end

link download

Exercise-1-2
# Try out the flickr.rb library http://redgreenblu.com/flickr/
# Use it to find interesting photos based on users or tags
# store some of the information in a sqlite database

require 'rubygems'
require 'flickr' # insanely easy flickr library
require 'sqlite3'

# NOTE: create the sqlite3 database beforehand or do it in code.
db = SQLite3::Database.new('flickr.db')

flickr = Flickr.new
dedi = flickr.users('dedi')

criteria = { 'user_id' => dedi.id, 'tags' => 'itp', 'privacy_filter' => '1' }

for photo in flickr.photos(criteria)
  db.execute("sql statement")
end

link download

Exercise-2-1
require 'rubygems'
require 'active_record'
require 'utils'

# this is init_db from utils.rb
# check out all the source through subversion
#
# http://social.itp.nyu.edu/dedi/svn/rails.itp
#
# username: itp with the usual password
#

#def init_db
#  logfile = '/Users/dedi/Documents/itp/awd/examples/week2/shows.log'#
#
#  # let's warm up the database goodness
#  ActiveRecord::Base.logger = Logger.new(logfile)
#  ActiveRecord::Base.colorize_logging = false
#  ActiveRecord::Base.establish_connection(
#    :adapter => 'sqlite3',
#    :database => 'db/shows.db' )
#end
init_db() # kick off ActiveRecord

class Show < ActiveRecord::Base
  belongs_to :rating
  belongs_to :genre
end

class Rating < ActiveRecord::Base
  has_many :shows
end
class Genre < ActiveRecord::Base
  has_many :shows
end

if __FILE__ == $0
  command = ARGV[0]

  case command
  when 'help'
    usage =  %Q{USAGE: ruby tv.rb command parameters\n\n}
    usage << %Q{migrate\t\t- make db changes with migrations\n}
    usage << %Q{list\t\t- list shows\n}
    usage << %Q{day\t\"day"\t- list shows on day\n}
    usage << %Q{name\t"name"\t- find by name\n}
    usage << %Q{rate\t"name"\t- add rating to show\n}
    usage << %Q{genre\t"name"\t- add genre to show\n}
    usage << %Q{add\t"name" "description" "day"\t- add a show\n}
    print usage

  when 'name'
    @shows = Show.find_by_name ARGV[1]
    list_shows(@shows)

  when 'add'
    @show = Show.create :name => ARGV[1], :description => ARGV[2],
      :day => to_day_id(ARGV[3])

  when 'day'
    @shows = Show.find_by_day to_day_id(ARGV[1])
    list_shows(@shows)

  when 'rate'
    @show = Show.find_by_name ARGV[1]
    @rating = Rating.find_by_audience(ARGV[2])

    @show.rating = @rating
    puts "Rating added" if @show.save

  when 'genre'
    @show = Show.find_by_name ARGV[1]
    @genre = Genre.find_by_name(ARGV[2])

    @show.genre = @genre
    puts "Genre added" if @show.save 

  when 'migrate'
    ActiveRecord::Base.logger = Logger.new(STDERR)
    ActiveRecord::Base.colorize_logging = true
    migrate(ENV["VERSION"] ? ENV["VERSION"].to_i : nil)

  else
    @shows = Show.find :all, :order => 'day asc'
    list_shows(@shows)
  end
end

link download

Exercise-3-1
### Assertions found in the test/unit library
### originally found here http://manuals.rubyonrails.com/read/chapter/24
### modified with examples

require 'test/unit'

class BigTestOfAssertions < Test::Unit::TestCase
  # assert( boolean, [msg] )
  # ensures the object/expression is true

  def test_boolean
    assert( 1+1 == 2 ) # => true
  end

  # assert_equal( obj1, obj2, [msg] )
  # ensures obj1 == obj2 is true 

  def test_equal
    assert_equal( "hello", "HELLO".downcase ) # => true
  end
  
  # assert_same( obj1, obj2, [msg] ) 
  # ensures obj1.equal?(obj2) is true
  # assert_not_same( obj1, obj2, [msg] )
  # ensures obj1.equal?(obj2) is false

  def test_sameness
    a = "test"
    b = a
    c = "test"

    assert_same(a, b) # => true
    assert_not_same(a, c) # => true
  end

  # assert_nil( obj, [msg] )
  # ensures obj.nil? is true
  # assert_not_nil( obj, [msg] )
  # ensures obj.nil? is false

  def test_nilness
    var = "not nil"

    assert_nil(nil) # => true
    assert_not_nil(var) # => true
  end

  # assert_match( regexp, string, [msg] )
  # ensures a string matches the regular expression
  # assert_no_match( regexp, string, [msg] )
  # ensures a string doesn’t matches the regular expression

  def test_regexp
    assert_match(/fish/, "dog cat fish hamster") # => true
    assert_no_match(/baby/,"dog cat fish hamster") # => false
  end

  # assert_in_delta( expecting, actual, delta, [msg] )
  # ensures the numbers expecting and actual are within delta of each other

  def test_delta
    result = 7
    assert_in_delta(5, result, 3) # => true
  end

  # assert_raises( exceptions ){ block }
  # ensures a block raises one of the comma-separated exceptions
  # assert_nothing_raised( exceptions ){ block }
  # ensures a block doesn’t raise one of the comma-separated exceptions

  def test_exceptions
    assert_raises(Errno::ENOENT) { f = File.open('not-exists.txt') }  # => true
  end

  # assert_instance_of( class, obj, [msg] )
  # ensures obj is the class type
  # assert_kind_of( class, obj, [msg] )
  # ensures obj is or descends from class

  def test_classes
    assert_instance_of(Fixnum, 1) # => true
    assert_kind_of(Object, 1) # => true
    assert_kind_of(Numeric, 1) # => true
  end

  def test_methods
    # assert_respond_to( obj, symbol, [msg] )
    # ensures obj has a method called symbol

    assert_respond_to(1, :zero?) # => true

    # assert_operator( obj1, operator, obj2, [msg] )
    # ensures obj1.operator(obj2) is true

    assert_operator(1, :equal?, 1) # => true

    # assert_send( array, [msg] )
    # ensures that executing the method listed in array[1] on the object in array[0] 
    # with the parameters of array[ 2 and up ] is true.

    array = [0, :zero?]
    assert_send(array) # => true
    array = [1, :==, 1]
    assert_send(array) # => true
  end
  
  # flunk ( [msg] )
  # ensures failure
  def test_failure
    # flunk("This will always fail.  Kind of sad.")
  end
end

link download

Exercise-3-2
## Rails specific assertions
## originally found here http://manuals.rubyonrails.com/read/chapter/28
## modified for examples

## Rails Controller Response Assertions

# assert_template ( expected_template, [msg] )
# ensures the expected template was responsible for rendering.

assert_template("user/profile") # asserts that app/views/user/profile.rhtml was rendered

# assert_response ( type_or_code, [msg] )
# ensures the response type/status code is as expected
#   :success (status code is 200)
#   :redirect (status code is within 300..399)
#   :missing (status code is 404)
#   :error (status code is within 500..599)
#   :any number (to specifically reference a particular status code)

assert_response :success      # page rendered ok
assert_response :redirect     # we've been redirected
assert_response :missing      # not found
assert_response 505           # status code was 505

# assert_redirected_to ( options={}, [msg] )
# ensures we’ve been redirected to a specific place within our application

assert_redirected_to :controller => 'widget', :action => 'view', :id => 555

## Rails Tag Assertions

# assert_tag ( options )
# ensures that a tag or text exists.
# assert_no_tag ( options )
# ensures that the tag does not exist.

assert_tag :tag => "span" # assert that there is a "span" tag
assert_tag :tag => "span", :parent => { :tag => "div" } # "span" inside a "div" 
assert_tag :tag => "span", :ancestor => { :tag => "table" } # "span" somewhere inside a table
assert_tag :tag => "span", :child => { :tag => "em" } # "span" with at least one "em" child

# assert that there is a "span" containing a (possibly nested) "strong" tag.
assert_tag :tag => "span", :descendant => { :tag => "strong" }

# assert that there is a "span" containing between 2 and 4 "em" tags
# as immediate children
assert_tag :tag => "span",
           :children => { :count => 2..4, :only => { :tag => "em" } }

## Rails Routing Assertions

# assert_generates ( expected_path, options, defaults={}, extras = {}, [msg] )
# ensures that the options map to the expected_path

opts = {:controller => "movies", :action => "movie", :id => "60"}
assert_generates "movies/movie/60", opts

# assert_recognizes ( expected_options, path, extras={}, [msg] )
# ensures that when the path is chopped up into pieces, it is equal to 
#   expected_options. Essentially, the opposite of assert_generates.

opts = {:controller => "movies", :action => "movie", :id => "60"}
assert_recognizes opts, "/movies/movie/60"

# assert_routing ( path, options, defaults={}, extras={}, [msg] )
# ensures that the path resolves into options, and the options, resolves into path
# If you’re going to test your routes, this assertion might be your best bet.

opts = {:controller => "movies", :action => "movie", :id => "60"}
assert_routing "movies/movie/60", opts

link download