UNPKG

installment-calculations

Version:

Calculate payment installments (and other useful details) based on start/end dates, interval and target amount

205 lines (179 loc) 9.47 kB
var chai = require('chai'); chai.use(require('chai-datetime')); var expect = chai.expect; var IC = require('../index'); var moment = require('moment'); describe('getTransactionsArray', function() { it('should calculate correct MONTHLY dates/amounts when a date of the 30th is provided', function() { const startDate = moment().year(2015).month(0).date(30).toDate(); const dateTarget = moment().year(2015).month(11).date(31).toDate(); const savingsTarget = 1025; const depositInterval = 'MONTHLY'; const transArr = IC.getTransactionsArray(savingsTarget, dateTarget, startDate, depositInterval); const amounts = transArr.map(function(x) { return x.amount; }); const days = transArr.map(function(x) { return moment(x.date).format('D'); }); const months = transArr.map(function(x) { return moment(x.date).format('M'); }); expect(transArr.length).to.equal(12); expect(amounts).to.eql([90, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85]); expect(days).to.eql(['30', '28', '30', '30', '30', '30', '30', '30', '30', '30', '30', '30']); expect(months).to.eql(['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']); }); it('should calculate correct MONTHLY dates/amounts when a date of the 31th is provided', function() { const startDate = moment().year(2015).month(0).date(31).toDate(); const dateTarget = moment().year(2015).month(11).date(15).toDate(); const savingsTarget = 1025; const depositInterval = 'MONTHLY'; const transArr = IC.getTransactionsArray(savingsTarget, dateTarget, startDate, depositInterval); const amounts = transArr.map(function(x) { return x.amount; }); const days = transArr.map(function(x) { return moment(x.date).format('D'); }); const months = transArr.map(function(x) { return moment(x.date).format('M'); }); expect(transArr.length).to.equal(11); expect(amounts).to.eql([95, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93]); expect(days).to.eql(['31', '28', '31', '30', '31', '30', '31', '31', '30', '31', '30']); expect(months).to.eql(['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11']); }); it('should return array of objects with date and amount values for a WEEKLY interval', function() { const startDate = moment().year(2015).month(0).date(1).toDate(); const dateTarget = moment().year(2015).month(2).date(8).toDate(); const savingsTarget = 1025; const depositInterval = 'WEEKLY'; const transArr = IC.getTransactionsArray(savingsTarget, dateTarget, startDate, depositInterval); const amounts = transArr.map(function(x) { return x.amount; }); const days = transArr.map(function(x) { return moment(x.date).format('D'); }); const months = transArr.map(function(x) { return moment(x.date).format('M'); }); expect(amounts).to.eql([107, 102, 102, 102, 102, 102, 102, 102, 102, 102]); expect(days).to.eql(['1', '8', '15', '22', '29', '5', '12', '19', '26', '5']); expect(months).to.eql(['1', '1', '1', '1', '1', '2', '2', '2', '2', '3']); }); }); describe('numberOfWeeksBetween', function() { it('should return the number of full weeks between two dates', function() { const startDate = moment().year(2015).month(1).date(1).toDate(); const endDate = moment().year(2016).month(1).date(1).toDate(); const weeksBetween = IC.numberOfWeeksBetween(startDate, endDate); expect(weeksBetween).to.equal(52); }); it('should return a negative number of weeks when end date is before start date', function() { const endDate = moment().year(2015).month(1).date(1).toDate(); const startDate = moment().year(2016).month(1).date(1).toDate(); const weeksBetween = IC.numberOfWeeksBetween(startDate, endDate); expect(weeksBetween).to.equal(-52); }); it('should return 0 when start and end is on the same week', function() { const startDate = moment().year(2015).month(1).date(1).toDate(); const endDate = startDate; const weeksBetween = IC.numberOfWeeksBetween(startDate, endDate); expect(weeksBetween).to.equal(0); }); }); describe('numberOfMonthsBetween', function() { it('should return the number of full months between two dates', function() { const startDate = moment().year(2015).month(1).date(1).toDate(); const endDate = moment().year(2016).month(1).date(1).toDate(); const monthsBetween = IC.numberOfMonthsBetween(startDate, endDate); expect(monthsBetween).to.equal(12); }); it('should return a negative number of months when end date is before start date', function() { const endDate = moment().year(2015).month(1).date(1).toDate(); const startDate = moment().year(2016).month(1).date(1).toDate(); const monthsBetween = IC.numberOfMonthsBetween(startDate, endDate); expect(monthsBetween).to.equal(-12); }); it('should return 0 when start and end is on the same month', function() { const startDate = moment().year(2015).month(1).date(1).toDate(); const endDate = startDate; const monthsBetween = IC.numberOfMonthsBetween(startDate, endDate); expect(monthsBetween).to.equal(0); }); }); describe('getNextInstanceOfDate', function() { it('should return the next occurence when in the month after', function() { const startDate = moment().year(2015).month(0).date(1).startOf('day').toDate(); const expectedDate = moment().year(2015).month(1).date(1).startOf('day').toDate(); const nextInstanceOfDate = IC.getNextInstanceOfDate(1, startDate); expect(nextInstanceOfDate).to.equalDate(expectedDate); }); it('should return the next occurence when in the same month', function() { const startDate = moment().year(2015).month(0).date(1).startOf('day').toDate(); const expectedDate = moment().year(2015).month(0).date(25).startOf('day').toDate(); const nextInstanceOfDate = IC.getNextInstanceOfDate(25, startDate); expect(nextInstanceOfDate).to.equalDate(expectedDate); }); }); describe('getNextInstanceOfDay', function() { it('should return the next weekday occurence when in the week after', function() { // Week 1 Thursday const startDate = moment().year(2015).month(0).date(1).startOf('day').toDate(); // Week 2 Tuesday const expectedDate = moment().year(2015).month(0).date(6).startOf('day').toDate(); const nextInstanceOfDay = IC.getNextInstanceOfDay(2, startDate); expect(nextInstanceOfDay).to.equalDate(expectedDate); }); it('should return the next weekday occurence when in the same week', function() { // Week 2 Tuesday const startDate = moment().year(2015).month(0).date(6).startOf('day').toDate(); // Week 2 Thursday const expectedDate = moment().year(2015).month(0).date(8).startOf('day').toDate(); const nextInstanceOfDay = IC.getNextInstanceOfDay(4, startDate); expect(nextInstanceOfDay).to.equalDate(expectedDate); }); it('should return the next weekday occurence when in the week after when the same day', function() { // Week 2 Tuesday const startDate = moment().year(2015).month(0).date(6).startOf('day').toDate(); // Week 3 Tuesday const expectedDate = moment().year(2015).month(0).date(13).startOf('day').toDate(); const nextInstanceOfDay = IC.getNextInstanceOfDay(2, startDate); expect(nextInstanceOfDay).to.equalDate(expectedDate); }); }); describe('calculateInstallmentAmount', function() { it('should calculate amount per installment', function() { const targetAmount = 500; const numberOfInstallments = 10; const amount = IC.calculateInstallmentAmount(targetAmount, numberOfInstallments); expect(amount).to.equal(50); }); it('should round down installmentAmount when decimal', function() { const targetAmount = 499; const numberOfInstallments = 10; const amount = IC.calculateInstallmentAmount(targetAmount, numberOfInstallments); expect(amount).to.equal(49); }); }); describe('calculateLastInstallmentAmount', function() { it('should calculate last Installment Amount', function() { const targetAmount = 600; const numberOfInstallments = 21; const expectedLastInstallment = 40; const lastInstallment = IC.calculateLastInstallmentAmount(targetAmount, numberOfInstallments); expect(lastInstallment).to.equal(expectedLastInstallment); }); }); describe('calculateInstallmentNumber', function() { it('should calculate number of installments give targetAmount and installmentAmount', function() { const targetAmount = 500; const installmentAmount = 100; const amount = IC.calculateInstallmentNumber(targetAmount, installmentAmount); expect(amount).to.equal(5); }); it('should round up number of installments when decimal', function() { const targetAmount = 500; const installmentAmount = 480; const amount = IC.calculateInstallmentNumber(targetAmount, installmentAmount); expect(amount).to.equal(2); }); }); describe('installmentAmountsAreUnequal', function() { it('should return true if installment amount is a float', function() { const savingsTarget = 520; const numberOfInstallments = 100; const isUnequal = IC.installmentAmountsAreUnequal(savingsTarget, numberOfInstallments); expect(isUnequal).to.equal(true); }); it('should return false if installment amount is an integer', function() { const savingsTarget = 500; const numberOfInstallments = 100; const isUnequal = IC.installmentAmountsAreUnequal(savingsTarget, numberOfInstallments); expect(isUnequal).to.equal(false); }); });