Functional Weave
Code in TypeScript

banking.overdraft-interest@1.0.0

vectors.json

6,868 bytes · view raw

[
 {
  "name": "\u00a3500 overdrawn all month at 39.9%, no buffer",
  "args": [
   [
    {
     "date": "2026-03-01",
     "balance": {
      "minor": -50000,
      "currency": "GBP"
     }
    }
   ],
   "2026-03-01",
   "2026-04-01",
   3990,
   {
    "minor": 0,
    "currency": "GBP"
   },
   "act-365f",
   "half-up"
  ],
  "expect": {
   "interest": {
    "minor": 1694,
    "currency": "GBP"
   },
   "daysOverdrawn": 31,
   "daysCharged": 31
  }
 },
 {
  "name": "a \u00a3250 buffer: only the \u00a3250 above it is charged",
  "args": [
   [
    {
     "date": "2026-03-01",
     "balance": {
      "minor": -50000,
      "currency": "GBP"
     }
    }
   ],
   "2026-03-01",
   "2026-04-01",
   3990,
   {
    "minor": 25000,
    "currency": "GBP"
   },
   "act-365f",
   "half-up"
  ],
  "expect": {
   "interest": {
    "minor": 847,
    "currency": "GBP"
   },
   "daysOverdrawn": 31,
   "daysCharged": 31
  }
 },
 {
  "name": "within the buffer all month: no interest",
  "args": [
   [
    {
     "date": "2026-03-01",
     "balance": {
      "minor": -20000,
      "currency": "GBP"
     }
    }
   ],
   "2026-03-01",
   "2026-04-01",
   3990,
   {
    "minor": 25000,
    "currency": "GBP"
   },
   "act-365f",
   "half-up"
  ],
  "expect": {
   "interest": {
    "minor": 0,
    "currency": "GBP"
   },
   "daysOverdrawn": 31,
   "daysCharged": 0
  }
 },
 {
  "name": "in and out of the overdraft during the month",
  "args": [
   [
    {
     "date": "2026-03-01",
     "balance": {
      "minor": 10000,
      "currency": "GBP"
     }
    },
    {
     "date": "2026-03-10",
     "balance": {
      "minor": -80000,
      "currency": "GBP"
     }
    },
    {
     "date": "2026-03-20",
     "balance": {
      "minor": -30000,
      "currency": "GBP"
     }
    },
    {
     "date": "2026-03-25",
     "balance": {
      "minor": 5000,
      "currency": "GBP"
     }
    }
   ],
   "2026-03-01",
   "2026-04-01",
   3990,
   {
    "minor": 25000,
    "currency": "GBP"
   },
   "act-365f",
   "half-up"
  ],
  "expect": {
   "interest": {
    "minor": 629,
    "currency": "GBP"
   },
   "daysOverdrawn": 15,
   "daysCharged": 15
  }
 },
 {
  "name": "in credit all month: no interest and no overdrawn days",
  "args": [
   [
    {
     "date": "2026-03-01",
     "balance": {
      "minor": 150000,
      "currency": "GBP"
     }
    }
   ],
   "2026-03-01",
   "2026-04-01",
   3990,
   {
    "minor": 0,
    "currency": "GBP"
   },
   "act-365f",
   "half-up"
  ],
  "expect": {
   "interest": {
    "minor": 0,
    "currency": "GBP"
   },
   "daysOverdrawn": 0,
   "daysCharged": 0
  }
 },
 {
  "name": "a balance exactly at the buffer is not charged",
  "args": [
   [
    {
     "date": "2026-03-01",
     "balance": {
      "minor": -25000,
      "currency": "GBP"
     }
    }
   ],
   "2026-03-01",
   "2026-04-01",
   3990,
   {
    "minor": 25000,
    "currency": "GBP"
   },
   "act-365f",
   "half-up"
  ],
  "expect": {
   "interest": {
    "minor": 0,
    "currency": "GBP"
   },
   "daysOverdrawn": 31,
   "daysCharged": 0
  }
 },
 {
  "name": "opening balance from before the statement",
  "args": [
   [
    {
     "date": "2026-02-20",
     "balance": {
      "minor": -100000,
      "currency": "GBP"
     }
    },
    {
     "date": "2026-03-15",
     "balance": {
      "minor": 0,
      "currency": "GBP"
     }
    }
   ],
   "2026-03-01",
   "2026-04-01",
   1990,
   {
    "minor": 0,
    "currency": "GBP"
   },
   "act-365f",
   "half-up"
  ],
  "expect": {
   "interest": {
    "minor": 763,
    "currency": "GBP"
   },
   "daysOverdrawn": 14,
   "daysCharged": 14
  }
 },
 {
  "name": "a zero-rate overdraft counts days but charges nothing",
  "args": [
   [
    {
     "date": "2026-03-01",
     "balance": {
      "minor": -100000,
      "currency": "GBP"
     }
    }
   ],
   "2026-03-01",
   "2026-04-01",
   0,
   {
    "minor": 0,
    "currency": "GBP"
   },
   "act-365f",
   "half-up"
  ],
  "expect": {
   "interest": {
    "minor": 0,
    "currency": "GBP"
   },
   "daysOverdrawn": 31,
   "daysCharged": 31
  }
 },
 {
  "name": "customer-friendly rounding down",
  "args": [
   [
    {
     "date": "2026-03-01",
     "balance": {
      "minor": -12345,
      "currency": "GBP"
     }
    }
   ],
   "2026-03-01",
   "2026-03-08",
   3990,
   {
    "minor": 0,
    "currency": "GBP"
   },
   "act-365f",
   "down"
  ],
  "expect": {
   "interest": {
    "minor": 94,
    "currency": "GBP"
   },
   "daysOverdrawn": 7,
   "daysCharged": 7
  }
 },
 {
  "name": "a leap-year February on ACT/365F",
  "args": [
   [
    {
     "date": "2028-02-01",
     "balance": {
      "minor": -100000,
      "currency": "GBP"
     }
    }
   ],
   "2028-02-01",
   "2028-03-01",
   3990,
   {
    "minor": 0,
    "currency": "GBP"
   },
   "act-365f",
   "half-up"
  ],
  "expect": {
   "interest": {
    "minor": 3170,
    "currency": "GBP"
   },
   "daysOverdrawn": 29,
   "daysCharged": 29
  }
 },
 {
  "name": "a negative rate is refused",
  "args": [
   [
    {
     "date": "2026-03-01",
     "balance": {
      "minor": -100,
      "currency": "GBP"
     }
    }
   ],
   "2026-03-01",
   "2026-04-01",
   -1,
   {
    "minor": 0,
    "currency": "GBP"
   },
   "act-365f",
   "half-up"
  ],
  "expectError": "annualRateBasisPoints must not be negative"
 },
 {
  "name": "a negative buffer is refused",
  "args": [
   [
    {
     "date": "2026-03-01",
     "balance": {
      "minor": -100,
      "currency": "GBP"
     }
    }
   ],
   "2026-03-01",
   "2026-04-01",
   3990,
   {
    "minor": -1,
    "currency": "GBP"
   },
   "act-365f",
   "half-up"
  ],
  "expectError": "interestFreeBuffer must not be negative"
 },
 {
  "name": "a buffer in another currency is refused",
  "args": [
   [
    {
     "date": "2026-03-01",
     "balance": {
      "minor": -100,
      "currency": "GBP"
     }
    }
   ],
   "2026-03-01",
   "2026-04-01",
   3990,
   {
    "minor": 0,
    "currency": "EUR"
   },
   "act-365f",
   "half-up"
  ],
  "expectError": "currency mismatch"
 },
 {
  "name": "balances out of order are refused",
  "args": [
   [
    {
     "date": "2026-03-05",
     "balance": {
      "minor": -100,
      "currency": "GBP"
     }
    },
    {
     "date": "2026-03-01",
     "balance": {
      "minor": -200,
      "currency": "GBP"
     }
    }
   ],
   "2026-03-01",
   "2026-04-01",
   3990,
   {
    "minor": 0,
    "currency": "GBP"
   },
   "act-365f",
   "half-up"
  ],
  "expectError": "strictly ascending date order"
 },
 {
  "name": "a first balance after the statement starts is refused",
  "args": [
   [
    {
     "date": "2026-03-05",
     "balance": {
      "minor": -100,
      "currency": "GBP"
     }
    }
   ],
   "2026-03-01",
   "2026-04-01",
   3990,
   {
    "minor": 0,
    "currency": "GBP"
   },
   "act-365f",
   "half-up"
  ],
  "expectError": "after fromIso"
 }
]