Skip to content

Instantly share code, notes, and snippets.

@maxsilver
Forked from zdennis/report-exercise.rb
Last active December 13, 2015 20:59
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 maxsilver/4974205 to your computer and use it in GitHub Desktop.
Save maxsilver/4974205 to your computer and use it in GitHub Desktop.
Names incoming parameters for clarity.
#
# The goal of this exercise is work on identifying abstraction which helps simplify, document,
# and separate the concerns going on in file.
#
# Exercise:
# * Find related ideas in the below code
# * Abstract them out (methods, modules, classes, etc, you pick!)
# * If you find multiple ways, then do a separate gist for each way.
# * Rinse repeat until you see no other ways.
#
# Note: there is not enough of the code-base to run this code, so in order to run
# the code you'll have to implement the missing pieces.
# typical usage :
# ship = Ship.find_by_name("USS Enterprise")
# LogReport.new({
# :title => ship.name,
# :logs => ship.logs.active
# })
class LogReport
def initialize(options)
@title = options[:title] + " Report"
@text = options[:logs].map{ |log| log.status }
end
def generate(format)
if format == :plain
generate_plain
elsif format == :html
generate_html
elsif format == :json
generate_json
else
raise "Unknown report format: #{format.inspect}"
end
end
private
def generate_plain
output = []
output << "###### #{@title} ######"
@text.each_line do |line|
output << line
end
output.join "\n"
end
def generate_html
output = "<html>"
output << " <head>"
output << " <title>#{@title}</title>"
output << " </head>"
output << " <body>"
@text.each do |line|
output << " <p>#{line}</p>"
end
output << " </body>"
output << "</html>"
output
end
def generate_json
output = { title: @title, lines: [] }
@text.each do |line|
output[:lines] << line
end
output
end
end
class Ship < ActiveRecord::Base
has_many :logs
attr_accessor :name
end
class Log < ActiveRecord::Base
belongs_to :ship
attr_accessor :date, :message, :alert_level
scope :active, lambda do
where(
"date >= '#{Time.now.year}-01-01' AND state=?", "active"
).order("date DESC")
def status
status = "#{date}: #{message} (#{alert_level})"
end
end
# spec/models/contact.rb
require 'spec_helper'
describe LogReport do
before(:each) do
logs = [
Log.new(:date => Date.parse("1/1/2001"), :message => "Foo", :alert_level => "Red"),
Log.new(:date => Date.parse("1/2/2001"), :message => "Bar", :alert_level => "Blue")
]
@report = Factory.build(:log_report, :logs => logs, :title => "Ship")
end
it "is creatable" do
@report.should_be valid
end
it "generates a plain report" do
text = "###### #{@title} ######\n"
text += "2001-01-01: Foo (Red)"
text += "2001-01-02: Bar (Blue)"
@report.generate(:plain).should eq(text)
end
it "generates a html report" do
html = @report.generate(:html)
html.should include("<p>2001-01-01: Foo (Red)</p>")
html.should include("<p>2001-01-02: Foo (Blue)</p>")
end
it "generates a json report" do
contents = JSON.parse(@report.generate(:json))
contents[0].should eq("2001-01-01: Foo (Red)")
contents[1].should eq("2001-01-01: Foo (Red)")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment