Skip to content

Instantly share code, notes, and snippets.

@aks
Created December 31, 2013 06:09
Show Gist options
  • Save aks/8193251 to your computer and use it in GitHub Desktop.
Save aks/8193251 to your computer and use it in GitHub Desktop.
Sample demonstration ruby class and methods. Three files: polygon.rb, which defines simple polygons: square, rectangle, triangle, circle; test-polygon.rb, a set of simple unit tests of the Polygon class and methods, and finally, the test run output.
# polygon.rb
include Math
TAU = PI * 2
class Polygon
# o = Polygon.new :KIND, PARAMS
# o.kind
# o.area
# o.circum
# o.sides
# o.sizes or o.size
attr :sizes, :sides
def initialize kind, params # num_sides, area_calc, circum_calc, *sizes
@kind = kind
@sides = params[:sides] if params.key?(:sides)
@area_calc = params[:area] if params.key?(:area) # computes area - should be a lambda of "num_sides" variables
@circum_calc = params[:circum] if params.key?(:circum) # computes circumference - another lambda of "num_sides" variables
@sizes = params[:sizes] if params.key?(:sizes)
@sizes = params[:size] if params.key?(:size)
@sizes ||= [nil]
self
end
def area
@area_calc.call(*@sizes)
end
def circumference
@circum_calc.call(*@sizes)
end
alias circum circumference
# size attribute is really an alias for sizes, but enforcing single number
def size= num
@sizes = [num]
end
def size
@sizes.first
end
end
class Rectangle < Polygon
def initialize *sizes
super :Rectangle, {
:sides => 4,
:area => lambda {|a,b| a*b},
:circum => lambda {|a,b| 2*(a+b)},
:sizes => sizes[0,2]
}
end
end
class Square < Polygon
def initialize size
super :Square, {
:sides => 4,
:area => lambda {|a| a*a},
:circum => lambda {|a| 4*a},
:size => [size]
}
end
end
class Triangle < Polygon
def initialize *sizes
super :Triangle, {
:sides => 3,
:area => lambda {|a,b,c| s = (a + b + c) / 2 ; sqrt(s*(s-a)*(s-b)*(s-c)) },
:circum => lambda {|a,b,c| a+b+c},
:sizes => sizes[0,3]
}
end
end
class Circle < Polygon
def initialize size
super :Circle, {
:sides => 1,
:area => lambda{|r| PI*(r**2) },
:circum => lambda{|r| 2*PI*r },
:size => [size]
}
end
end
# end of Polygon.rb
# vim:ai:sw=2
$ ./test-polygon.rb -v
Run options: -v --seed 25294
# Running:
TestPolygon#test_triangle = 0.00 s = .
TestPolygon#test_rectangle = 0.00 s = .
TestPolygon#test_circle = 0.00 s = .
TestPolygon#test_square = 0.00 s = .
Finished in 0.001458s, 2743.4842 runs/s, 25377.2291 assertions/s.
4 runs, 37 assertions, 0 failures, 0 errors, 0 skips
#!/usr/bin/env ruby
# test-polygon.rb
#
$LOAD_PATH.unshift '.'
require 'polygon'
require 'minitest/autorun'
class TestPolygon < Minitest::Test
def setup
end
def check_methods cls, obj
assert_instance_of cls, obj
assert_respond_to obj, :area
assert_respond_to obj, :size
assert_respond_to obj, :circum
assert_respond_to obj, :sides
end
def check_values obj, params
params.keys.each{|key|
case key
when :area then assert_equal params[:area], obj.area
when :size then assert_equal params[:size], obj.size
when :sizes then assert_equal params[:sizes], obj.sizes
when :circum then assert_equal params[:circum], obj.circum
when :sides then assert_equal params[:sides], obj.sides
end
}
end
def test_circle
r = radius = 5
c1 = Circle.new radius
assert_instance_of Circle, c1
check_methods Circle, c1
check_values c1, :area => Math::PI*(radius**2),
:size => 5,
:circum => 2 * Math::PI*radius,
:sides => 1
end
def test_square
size = 5
sq1 = Square.new size
check_methods Square, sq1
check_values sq1, :area => size * size,
:size => size,
:circum => 2 * (size + size),
:sides => 4
end
def test_rectangle
sizes = [10, 5]
r1 = Rectangle.new *sizes
check_methods Rectangle, r1
check_values r1, :area => (sizes[0] * sizes[1]),
:sizes => sizes,
:circum => 2 * ( sizes[0] + sizes[1] ),
:sides => 4
end
def test_triangle
sizes = [4, 5, 6]
t1 = Triangle.new *sizes
check_methods Triangle, t1
check_values t1, :area => (s = (sizes.reduce(:+)/2); Math::sqrt(s*(s-sizes[0])*(s-sizes[1])*(s-sizes[2]))),
:sizes => sizes,
:circum => sizes.reduce(:+),
:sides => 3
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment