Skip to content

Instantly share code, notes, and snippets.

@netikular
Created September 25, 2011 12:08
Show Gist options
  • Save netikular/1240544 to your computer and use it in GitHub Desktop.
Save netikular/1240544 to your computer and use it in GitHub Desktop.
Answer to Ayende's blog post
#From blog post http://ayende.com/blog/108545/the-tax-calculation-challenge
require 'test/unit'
class Rate
def initialize(rate)
@percent = rate[:percent]
@min = rate[:min].to_f
@max = rate[:max].to_f
@range = @max - @min
end
def percent
return (@percent / 100.00).round(2)
end
def taxible(amount)
amount = amount.to_f
return @range if ((amount - @max) > 0)
return amount - @min if ((amount - @min) > 0)
return 0.0
end
def tax(amount)
(self.taxible(amount).round(2) * (self.percent))
end
end
class TaxMan
attr_accessor :rates,:amount
def profit
@rates.inject(0.0) do |memo, rate|
memo = memo + rate.tax(@amount)
memo.round(2)
end
end
end
#### TESTS
#
INFINITY = 1.0/0
DATA_RATES = [
{ :percent => 10, :min =>0,:max => 5070},
{ :percent => 14, :min =>5070,:max => 8660 },
{ :percent => 23, :min =>8660,:max => 14070 },
{ :percent => 30, :min =>14070,:max => 21240 },
{ :percent => 33, :min =>21240,:max => 40230 },
{ :percent => 45, :min =>40230,:max => INFINITY }
]
class TaxesTest < Test::Unit::TestCase
def setup
@tax_man = TaxMan.new
@tax_man.rates = DATA_RATES.map{|rate| Rate.new(rate)}
end
def test_should_do_the_first_level
@tax_man.amount = 5000
assert_equal 500.0, @tax_man.profit
end
def test_should_do_the_boundry_test_first_level
@tax_man.amount = 5070
assert_equal 507.0, @tax_man.profit
end
def test_should_do_the_bountry_test_second_level
@tax_man.amount = 8660
assert_equal 1009.6, @tax_man.profit
end
def test_should_do_the_second_level
@tax_man.amount = 5800
assert_equal 609.2, @tax_man.profit
end
def test_should_do_the_third_level
@tax_man.amount = 9000
assert_equal 1087.8, @tax_man.profit
end
def test_should_do_the_fourth_level
@tax_man.amount = 15000
assert_equal 2532.9, @tax_man.profit
end
def test_should_do_the_fifth_level
@tax_man.amount = 50000
assert_equal 15068.1, @tax_man.profit
end
def test_find_the_amount_from_the_rate
rate = Rate.new(DATA_RATES[0])
assert_equal 5070 , rate.taxible(9000)
rate = Rate.new(DATA_RATES[1])
assert_equal 3590 , rate.taxible(9000)
rate = Rate.new(DATA_RATES[2])
assert_equal 340 , rate.taxible(9000)
rate = Rate.new(DATA_RATES[3])
assert_equal 0 , rate.taxible(9000)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment