mirror of
https://github.com/IT4Change/gradido.git
synced 2026-03-01 12:44:43 +00:00
100 lines
3.9 KiB
TypeScript
100 lines
3.9 KiB
TypeScript
import { Decimal } from 'decimal.js-light'
|
|
|
|
import { calculateDecay, compoundInterest, decayFormula, decayFormulaFast } from './decay'
|
|
|
|
describe('utils/decay', () => {
|
|
describe('decayFormula', () => {
|
|
it('has base 0.99999997802044727', () => {
|
|
const amount = new Decimal(1.0)
|
|
const seconds = 1
|
|
// TODO: toString() was required, we could not compare two decimals
|
|
expect(decayFormula(amount, seconds).toString()).toBe('0.999999978035040489732012')
|
|
})
|
|
|
|
it('with large values', () => {
|
|
const amount = new Decimal(100.0)
|
|
const seconds = 1209600
|
|
expect(decayFormula(amount, seconds).toString()).toBe('97.3781030481034505778419')
|
|
})
|
|
|
|
it('with one year', () => {
|
|
const amount = new Decimal(100.0)
|
|
const seconds = 31556952
|
|
expect(decayFormula(amount, seconds).toString()).toBe('49.99999999999999999999999')
|
|
})
|
|
|
|
it('has correct backward calculation', () => {
|
|
const amount = new Decimal(1.0)
|
|
const seconds = -1
|
|
expect(decayFormula(amount, seconds).toString()).toBe('1.000000021964959992727444')
|
|
})
|
|
// we get pretty close, but not exact here, skipping
|
|
|
|
it.skip('has correct forward calculation', () => {
|
|
const amount = new Decimal(1.0).div(
|
|
new Decimal('0.99999997803504048973201202316767079413460520837376'),
|
|
)
|
|
const seconds = 1
|
|
expect(decayFormula(amount, seconds).toString()).toBe('1.0')
|
|
})
|
|
})
|
|
|
|
describe('decayFormulaFast', () => {
|
|
it('work like expected with small values', () => {
|
|
const amount = new Decimal(1.0)
|
|
const seconds = 1
|
|
expect(decayFormulaFast(amount, seconds).toString()).toBe('0.999999978035040489732012')
|
|
})
|
|
it('work like expected with large values', () => {
|
|
const amount = new Decimal(100.0)
|
|
const seconds = 1209600
|
|
expect(decayFormulaFast(amount, seconds).toString()).toBe('97.3781030481034505778419')
|
|
})
|
|
it('work like expected with one year', () => {
|
|
const amount = new Decimal(100.0)
|
|
const seconds = 31556952
|
|
expect(decayFormulaFast(amount, seconds).toString()).toBe('50')
|
|
})
|
|
it('work correct when calculating future decay', () => {
|
|
// for example on linked transaction
|
|
// if I have amount = 100 GDD and want to know how much GDD I must lock to able to pay
|
|
// decay in 14 days (1209600 seconds)
|
|
const amount = new Decimal(100.0)
|
|
const seconds = 1209600
|
|
expect(compoundInterest(amount, seconds).toString()).toBe('102.6924912992003635568199')
|
|
// if I lock 102.6924912992003635568199 GDD, I will have 99.99999999999999999999998 GDD after 14 days, not 100% but near enough
|
|
expect(decayFormulaFast(compoundInterest(amount, seconds), seconds).toString()).toBe('99.99999999999999999999998')
|
|
expect(compoundInterest(amount, seconds).toDecimalPlaces(4).toString()).toBe('102.6925')
|
|
// rounded to 4 decimal places it is working like a charm
|
|
expect(decayFormulaFast(new Decimal(
|
|
compoundInterest(amount, seconds).toDecimalPlaces(4)),
|
|
seconds
|
|
).toDecimalPlaces(4).toString()).toBe('100')
|
|
})
|
|
})
|
|
|
|
it('has base 0.99999997802044727', () => {
|
|
const now = new Date()
|
|
now.setSeconds(1)
|
|
const oneSecondAgo = new Date(now.getTime())
|
|
oneSecondAgo.setSeconds(0)
|
|
expect(calculateDecay(new Decimal(1.0), oneSecondAgo, now).balance.toString()).toBe(
|
|
'0.999999978035040489732012',
|
|
)
|
|
})
|
|
|
|
it('returns input amount when from and to is the same', () => {
|
|
const now = new Date()
|
|
expect(calculateDecay(new Decimal(100.0), now, now).balance.toString()).toBe('100')
|
|
})
|
|
|
|
describe('calculateDecay called with invalid dates', () => {
|
|
it('throws an error when to is before from', () => {
|
|
const now = new Date()
|
|
const oneSecondAgo = new Date(now.getTime())
|
|
oneSecondAgo.setSeconds(0)
|
|
expect(() => calculateDecay(new Decimal(1.0), now, oneSecondAgo)).toThrowError()
|
|
})
|
|
})
|
|
})
|