Guest User

JJoos

a guest
Oct 7th, 2011
293
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.56 KB | None | 0 0
  1. namespace Tax
  2. {
  3.     using System;
  4.     using System.Collections.Generic;
  5.     using System.Linq;
  6.     using Moq;
  7.     using NUnit.Framework;
  8.  
  9.     public interface ITaxBracket
  10.     {
  11.         decimal CalculateTax(decimal income);
  12.     }
  13.  
  14.     public class TaxBracket : ITaxBracket
  15.     {
  16.         public TaxBracket(decimal lowerBound, decimal upperBound, decimal taxRate)
  17.         {
  18.             if(lowerBound < 0 || upperBound < 0 || taxRate < 0)
  19.                 throw new ArgumentOutOfRangeException("lowerBound", "The lower bound should be non-negative.");
  20.  
  21.             if (lowerBound < 0 || upperBound < 0 || taxRate < 0)
  22.                 throw new ArgumentOutOfRangeException("upperBound", "The upper bound should be non-negative.");
  23.  
  24.             if (lowerBound < 0 || upperBound < 0 || taxRate < 0)
  25.                 throw new ArgumentOutOfRangeException("taxRate", "The tax rate should be non-negative.");
  26.  
  27.             if(upperBound <= lowerBound)
  28.                 throw new ArgumentException("The upper bound of the tax bracket should be non-negative.");
  29.  
  30.             this.lowerBound = lowerBound;
  31.             this.upperBound = upperBound;
  32.             this.taxRate = taxRate;
  33.         }
  34.  
  35.         readonly decimal lowerBound, upperBound, taxRate;
  36.  
  37.         public decimal CalculateTax(decimal income)
  38.         {
  39.             if (income < 0)
  40.                 throw new ArgumentOutOfRangeException("income", "Income should be non-negative.");
  41.  
  42.             if (lowerBound > income) return 0;
  43.  
  44.             var taxable = Math.Min(income - lowerBound, upperBound - lowerBound);
  45.             return taxable * (taxRate/100);
  46.         }
  47.        
  48.         #if DEBUG
  49.         [TestFixture]
  50.         class TaxBracketTests
  51.         {
  52.             [Test]
  53.             public void Constructor_CorrectParameters_ConstructsCorrectObject()
  54.             {
  55.                 var lowerBound = 1m;
  56.                 var upperBound = 2m;
  57.                 var taxRate = 1m;
  58.  
  59.                 var taxBracket = new TaxBracket(lowerBound, upperBound, taxRate);
  60.                
  61.                 Assert.AreEqual(lowerBound, taxBracket.lowerBound);
  62.                 Assert.AreEqual(upperBound, taxBracket.upperBound);
  63.                 Assert.AreEqual(taxRate, taxBracket.taxRate);
  64.             }
  65.  
  66.             [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
  67.             public void Constructor_LowerBoundIsNegative_Throws()
  68.             {
  69.                 new TaxBracket(-1m, 1m, 1m);
  70.             }
  71.  
  72.             [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
  73.             public void Constructor_UpperBoundIsNegative_Throws()
  74.             {
  75.                 new TaxBracket(1m, -1m, 1m);
  76.             }
  77.  
  78.             [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
  79.             public void Constructor_TaxRateIsNegative_Throws()
  80.             {
  81.                 new TaxBracket(1m, 1m, -1m);
  82.             }
  83.  
  84.             [Test, ExpectedException(typeof(ArgumentException))]
  85.             public void Constructor_LowerBoundGreaterThenUpperBound_Throws()
  86.             {
  87.                 new TaxBracket(2m, 1m, 1m);
  88.             }
  89.  
  90.             [Test, ExpectedException(typeof(ArgumentException))]
  91.             public void Constructor_LowerBoundEqualsUpperBound_Throws()
  92.             {
  93.                 new TaxBracket(1m, 1m, 1m);
  94.             }
  95.  
  96.             [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
  97.             public void CalculateTax_IncomeIsNegative_Throws()
  98.             {
  99.                 var taxBracket = new TaxBracket(1m, 2m, 100);
  100.  
  101.                 var tax = taxBracket.CalculateTax(-5m);
  102.  
  103.                 Assert.AreEqual(tax, 0m);
  104.             }
  105.  
  106.             [Test]
  107.             public void CalculateTax_IncomeIsBetweenLowerAndUpperBound_CorrectTax()
  108.             {
  109.                 var taxBracket = new TaxBracket(10m, 20m, 100);
  110.  
  111.                 var tax = taxBracket.CalculateTax(50m);
  112.  
  113.                 Assert.AreEqual(tax, 10m);
  114.             }
  115.  
  116.             [Test]
  117.             public void CalculateTax_LowerBoundIsZeroAndIncomeEqualsUpperBound_CorrectTax()
  118.             {
  119.                 var taxBracket = new TaxBracket(0m, 1m, 100);
  120.                
  121.                 var tax = taxBracket.CalculateTax(2m);
  122.  
  123.                 Assert.AreEqual(tax,1m);
  124.             }
  125.  
  126.             [Test]
  127.             public void CalculateTax_IncomeEqualsLowerBoundAndIsLessThenUpperBound_CorrectTax()
  128.             {
  129.                 var taxBracket = new TaxBracket(0m, 10m, 50);
  130.  
  131.                 var tax = taxBracket.CalculateTax(2m);
  132.  
  133.                 Assert.AreEqual(tax, 1m);
  134.             }
  135.  
  136.             [Test]
  137.             public void CalculateTax_IncomeGreaterThenLowerBoundAndEqualsUpperBound_CorrectTax()
  138.             {
  139.                 var taxBracket = new TaxBracket(0m, 10m, 50);
  140.  
  141.                 var tax = taxBracket.CalculateTax(10m);
  142.  
  143.                 Assert.AreEqual(tax, 5m);
  144.             }
  145.  
  146.             [Test]
  147.             public void CalculateTax_IncomeIsLessThenLowerBound_CorrectTax()
  148.             {
  149.                 var taxBracket = new TaxBracket(10m, 100m, 100);
  150.  
  151.                 var tax = taxBracket.CalculateTax(5m);
  152.  
  153.                 Assert.AreEqual(tax, 0m);
  154.             }
  155.         }
  156.         #endif
  157.     }
  158.  
  159.     public interface ITaxBracketSystem : IEnumerable<ITaxBracket>
  160.     {
  161.         decimal CalculateTax(Decimal income);
  162.         void Add(ITaxBracket item);
  163.     }
  164.  
  165.     public class TaxBracketSystem : List<ITaxBracket>, ITaxBracketSystem
  166.     {
  167.         public decimal CalculateTax(Decimal income)
  168.         {
  169.             if(income < 0)
  170.                 throw new ArgumentOutOfRangeException("income", "Income should be non-negative.");
  171.  
  172.             var tax = this.Sum(r => r.CalculateTax(income));
  173.             return Math.Round(tax,2);
  174.         }
  175.  
  176.         #if DEBUG
  177.         [TestFixture]
  178.         class TaxBracketSystemTests
  179.         {
  180.             [Test]
  181.             public void Constructor_OneTaxBracket_ConstructedCorrectObject ()
  182.             {
  183.                 var taxBracket = new TaxBracket(1m, 2m, 3m);
  184.                 var taxSystem = new TaxBracketSystem {taxBracket};
  185.  
  186.                 Assert.AreEqual(taxSystem[0], taxBracket);
  187.             }
  188.  
  189.             [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
  190.             public void CalculateTax_NegativeIncome_Throws()
  191.             {
  192.                 var taxSystem = new TaxBracketSystem();
  193.  
  194.                 taxSystem.CalculateTax(-100m);
  195.             }
  196.  
  197.             [Test]
  198.             public void CalculateTax_NoTaxBrackets_ZeroTax ()
  199.             {
  200.                 var taxSystem = new TaxBracketSystem();
  201.  
  202.                 var tax = taxSystem.CalculateTax(100m);
  203.  
  204.                 Assert.AreEqual(Decimal.Zero, tax);
  205.             }
  206.  
  207.             [Test]
  208.             public void CalculateTax_OneTaxBrackets_CorrectTax()
  209.             {
  210.                 var taxAmount = 100m;
  211.                 var taxBracketMoq = new Mock<ITaxBracket>();
  212.                 taxBracketMoq.Setup(taxBracket => taxBracket.CalculateTax(It.IsAny<decimal>())).Returns(taxAmount);
  213.                 var taxSystem = new TaxBracketSystem {taxBracketMoq.Object};
  214.  
  215.                 var calculatedTax = taxSystem.CalculateTax(1000m);
  216.  
  217.                 Assert.AreEqual(taxAmount, calculatedTax);
  218.             }
  219.  
  220.             [Test]
  221.             public void CalculateTax_TwoTaxBrackets_CorrectTax()
  222.             {
  223.                 var taxAmount1 = 100m;
  224.                 var taxBracketMoq1 = new Mock<ITaxBracket>();
  225.                 taxBracketMoq1.Setup(taxBracket => taxBracket.CalculateTax(It.IsAny<decimal>())).Returns(taxAmount1);
  226.  
  227.                 var taxAmount2 = 100m;
  228.                 var taxBracketMoq2 = new Mock<ITaxBracket>();
  229.                 taxBracketMoq2.Setup(taxBracket => taxBracket.CalculateTax(It.IsAny<decimal>())).Returns(taxAmount2);
  230.  
  231.                 var taxSystem = new TaxBracketSystem { taxBracketMoq1.Object, taxBracketMoq2.Object };
  232.  
  233.                 var tax = taxSystem.CalculateTax(1000m);
  234.  
  235.                 Assert.AreEqual(taxAmount1 + taxAmount2, tax);
  236.             }
  237.         }
  238.         #endif
  239.     }
  240.  
  241.     #if DEBUG
  242.     [TestFixture]
  243.     class TaxIntegrationTests
  244.     {
  245.         readonly ITaxBracketSystem israeliTaxSystem = new TaxBracketSystem
  246.         {
  247.             new TaxBracket(0, 5070, 10m),
  248.             new TaxBracket(5070, 8660, 14m),
  249.             new TaxBracket(8660, 14070, 23m),
  250.             new TaxBracket(14070, 21240, 30m),
  251.             new TaxBracket(21240, 40230, 33m),
  252.             new TaxBracket(40230, decimal.MaxValue, 45m)
  253.         };
  254.  
  255.         [Test]
  256.         public void IsraeliTaxSystem_IncomeIs05000_CorrectTax()
  257.         {            
  258.             var tax = israeliTaxSystem.CalculateTax(5000);
  259.  
  260.             Assert.AreEqual(500m, tax);
  261.         }
  262.  
  263.         [Test]
  264.         public void IsraeliTaxSystem_IncomeIs05800_CorrectTax()
  265.         {
  266.             var tax = israeliTaxSystem.CalculateTax(5800);
  267.  
  268.             Assert.AreEqual(609.2m, tax);
  269.         }
  270.  
  271.         [Test]
  272.         public void IsraeliTaxSystem_IncomeIs09000_CorrectTax()
  273.         {
  274.             var tax = israeliTaxSystem.CalculateTax(9000);
  275.  
  276.             Assert.AreEqual(1087.8m, tax);
  277.         }
  278.  
  279.         [Test]
  280.         public void IsraeliTaxSystem_IncomeIs15000_CorrectTax()
  281.         {
  282.             var tax = israeliTaxSystem.CalculateTax(15000);
  283.  
  284.             Assert.AreEqual(2532.9, tax);
  285.         }
  286.  
  287.         [Test]
  288.         public void IsraeliTaxSystem_IncomeIs50000_CorrectTax()
  289.         {
  290.             var tax = israeliTaxSystem.CalculateTax(50000);
  291.  
  292.             Assert.AreEqual(15068.1m, tax);
  293.         }
  294.     }
  295.     #endif
  296. }
  297.  
Advertisement
Add Comment
Please, Sign In to add comment