internal decimal?Calculate(string type, int days, RentalFees rentalFees) { if (days <= 0) { logger.LogError($"Unable to calculate price for negative day count: days = {days}!"); return(null); } switch (type) { case "Heavy": return(rentalFees.OneTimeFee + days * rentalFees.PremiumDailyFee); case "Regular": return(rentalFees.OneTimeFee + Math.Min(2, days) * rentalFees.PremiumDailyFee + Math.Max(0, days - 2) * rentalFees.RegularDailyFee); case "Specialized": return(Math.Min(3, days) * rentalFees.PremiumDailyFee + Math.Max(0, days - 3) * rentalFees.RegularDailyFee); default: logger.LogError($"Unable to calculate price for unknown equipment type: {type}!"); return(null); } }
public void CalculateCorrectPrice( Mock <OrderItemPriceCalculator> sutMock) { var rentalFees = new RentalFees { OneTimeFee = 1, RegularDailyFee = 10, PremiumDailyFee = 100 }; var testCases = new[] { new { type = "Heavy", days = 1, price = 101 }, // 1 + 1x100 new { type = "Heavy", days = 3, price = 301 }, // 1 + 3x100 new { type = "Heavy", days = 18, price = 1801 }, // 1 + 18x100 new { type = "Regular", days = 1, price = 101 }, // 1 + 1x100 new { type = "Regular", days = 2, price = 201 }, // 1 + 2x100 new { type = "Regular", days = 3, price = 211 }, // 1 + 2x100 + 1x10 new { type = "Regular", days = 7, price = 251 }, // 1 + 2x100 + 5x10 new { type = "Specialized", days = 1, price = 100 }, // 1x100 new { type = "Specialized", days = 3, price = 300 }, // 3x100 new { type = "Specialized", days = 4, price = 310 }, // 3x100 + 1x10 new { type = "Specialized", days = 28, price = 550 }, // 3x100 + 25x10 }; testCases.ToList().ForEach(t => Assert.Equal(t.price, sutMock.Object.Calculate(t.type, t.days, rentalFees))); }
public Price <TCurrency> CalculatePrice <TCurrency>(RentalFees <TCurrency> rentalFees, int rentalDays) where TCurrency : Currency { if (rentalDays <= 3) { return(rentalFees.PremiumDaily * rentalDays); } else { return(rentalFees.PremiumDaily * 3 + rentalFees.RegularDaily * (rentalDays - 3)); } }
public void TestConstructor() { var oneTime = new Price <DummyCurrency>(1, new DummyCurrency()); var premiumDaily = new Price <DummyCurrency>(2, new DummyCurrency()); var regularDaily = new Price <DummyCurrency>(3, new DummyCurrency()); var prices = new RentalFees <DummyCurrency>(oneTime, premiumDaily, regularDaily); // if properties would have its own price type (class), these asserts would become irrelevant, // as compiler would ensure incorrect price type won't be assigned to a property. Assert.Equal(oneTime, prices.OneTime); Assert.Equal(premiumDaily, prices.PremiumDaily); Assert.Equal(regularDaily, prices.RegularDaily); }
public void TestSpecializedEquipment(int oneTime, int premiumDaily, int regularDaily, int days, int expected) { var specialized = new SpecializedEquipment(); Assert.Equal(1, specialized.LoyaltyPoints); var prices = new RentalFees <DummyCurrency>( DummyCurrency.CreatePrice(oneTime), DummyCurrency.CreatePrice(premiumDaily), DummyCurrency.CreatePrice(regularDaily)); var expectedPrice = DummyCurrency.CreatePrice(expected); Assert.Equal(expectedPrice, specialized.CalculatePrice(prices, days)); }
public void TestHeavyEquipment(int oneTime, int premiumDaily, int regularDaily, int days, int expected) { var heavy = new HeavyEquipment(); Assert.Equal(2, heavy.LoyaltyPoints); var prices = new RentalFees <DummyCurrency>( DummyCurrency.CreatePrice(oneTime), DummyCurrency.CreatePrice(premiumDaily), DummyCurrency.CreatePrice(regularDaily)); var expectedPrice = DummyCurrency.CreatePrice(expected); Assert.Equal(expectedPrice, heavy.CalculatePrice(prices, days)); }
public void DoesNotCalculateForUnknownType( Mock <OrderItemPriceCalculator> sutMock, RentalFees rentalFees, string type, int days) { Assert.Null(sutMock.Object.Calculate(type, days, rentalFees)); }
public void DoesNotCalculateForZeroDays( Mock <OrderItemPriceCalculator> sutMock, RentalFees rentalFees) { Assert.Null(sutMock.Object.Calculate("Heavy", 0, rentalFees)); }
public void DoesNotCalculateForNegativeDays( Mock <OrderItemPriceCalculator> sutMock, RentalFees rentalFees, int days) { Assert.Null(sutMock.Object.Calculate("Heavy", -1 * days, rentalFees)); }
public static Invoice Create <TCurrency>(IEnumerable <EquipmentOrder> orderLines, RentalFees <TCurrency> fees) where TCurrency : Currency, new() { Price <TCurrency> total = new Price <TCurrency>(0, new TCurrency()); int loyaltyPoints = 0; var lines = orderLines.Select(orderLine => { var price = orderLine.CalculatePrice(fees); total = total.Add(price); // TODO: this logic is a part of "LoyaltyPoints" type loyaltyPoints += orderLine.CalculateLoyaltyPoints(); return(price.Print()); }).ToList(); return(new Invoice(total.Print(), loyaltyPoints, lines)); }
public Price <TCurrency> CalculatePrice <TCurrency>(RentalFees <TCurrency> fees) where TCurrency : Currency => ParseEquipmentType(Type).CalculatePrice(fees, RentalDays);
public Price <TCurrency> CalculatePrice <TCurrency>(RentalFees <TCurrency> rentalFees, int rentalDays) where TCurrency : Currency { return(rentalFees.OneTime + rentalFees.PremiumDaily * rentalDays); }