Skip to content

Instantly share code, notes, and snippets.

@nakajima
Forked from NYiPhoneDeveloper/gist:103179
Created April 28, 2009 23:04
Show Gist options
  • Select an option

  • Save nakajima/103463 to your computer and use it in GitHub Desktop.

Select an option

Save nakajima/103463 to your computer and use it in GitHub Desktop.
module Operations
def self.list
@list ||= []
end
class Base
def self.inherited(klass)
Operations.list << klass
end
def initialize(calculator)
@calculator = calculator
end
def x
@calculator.get(:x).to_f
end
def y
@calculator.get(:y)
end
def equals
result % 1 == 0 ? result.to_i : result
end
end
class Sum < Base
def self.key
"s"
end
def self.description
"Add values"
end
def result
x + y
end
end
class Quotient < Base
def self.key
"q"
end
def self.description
"Divide values"
end
def result
x / y
end
end
class Product < Base
def self.key
"p"
end
def self.description
"Multiply values"
end
def result
x * y
end
end
class Difference < Base
def self.key
"d"
end
def self.description
"Subtract values"
end
def result
x - y
end
end
end
class Calculator
include Operations
def initialize
@values = {}
end
def run
prompt(:x, 'First value: ')
prompt(:y, 'Second value: ')
say "These are your options:"
Operations.list.each do |operation|
say "To #{operation.to_s}, type '#{operation.key}'"
end
perform prompt(:operation, 'Choose an option: ')
end
def perform(key)
if op = Operations.list.detect { |operation| operation.key == key }
result = op.new(self).equals
say "Result is #{result}"
return result
end
end
def get(key)
@values[key].to_i
end
def set(key, val)
@values[key] = val
end
def prompt(key, description="Enter a number: ")
say description
@values[key] = STDIN.gets.chomp
end
private
def say(something)
STDOUT.puts(something)
end
end
Calculator.new.run if __FILE__ == $0
require 'rubygems'
require 'spec'
require 'rr'
require File.join(File.dirname(__FILE__), 'calculator')
Spec::Runner.configure do |c|
c.mock_with(:rr)
end
describe Calculator do
before(:each) do
stub(STDOUT).puts(anything)
stub(STDIN).gets.returns('1')
@calculator = Calculator.new
end
it "prompts for values" do
mock(STDIN).gets.returns('1')
result = @calculator.prompt(:x, 'Enter first number')
result.should == '1'
@calculator.get(:x).to_s.should == '1'
end
it "returns values" do
mock(STDIN).gets.returns('3')
@calculator.prompt(:foo)
@calculator.get(:foo).to_s.should == '3'
end
it "typecasts values" do
mock(STDIN).gets.returns('3')
@calculator.prompt(:y)
@calculator.get(:y).should == 3
end
describe "sum" do
it "adds x and y" do
@calculator.set(:x, '1')
@calculator.set(:y, '2')
@calculator.perform('s').should == 3
end
end
describe "quotient" do
it "finds quotient" do
@calculator.set(:x, '4')
@calculator.set(:y, '2')
@calculator.perform('q').should == 2
end
end
describe "product" do
it "multiplies x and y" do
@calculator.set(:x, 3)
@calculator.set(:y, 4)
@calculator.perform('p').should == 12
end
end
describe "difference" do
it "subtracts y from x" do
@calculator.set(:x, 10)
@calculator.set(:y, 3)
@calculator.perform('d').should == 7
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment