Functional Weave
Code in TypeScript

lending.ltv@1.0.1

vectors.json

8,641 bytes · view raw

[
 {
  "name": "\u00a3225,000 on a \u00a3300,000 house is exactly 75%",
  "args": [
   {
    "minor": 22500000,
    "currency": "GBP"
   },
   {
    "minor": 30000000,
    "currency": "GBP"
   },
   [
    {
     "maxBasisPoints": 6000,
     "label": "60% LTV"
    },
    {
     "maxBasisPoints": 7500,
     "label": "75% LTV"
    },
    {
     "maxBasisPoints": 8500,
     "label": "85% LTV"
    },
    {
     "maxBasisPoints": 9000,
     "label": "90% LTV"
    },
    {
     "maxBasisPoints": 9500,
     "label": "95% LTV"
    }
   ]
  ],
  "expect": {
   "basisPoints": 7500,
   "band": "75% LTV"
  }
 },
 {
  "name": "a penny over 75% is the 85% band",
  "args": [
   {
    "minor": 22500001,
    "currency": "GBP"
   },
   {
    "minor": 30000000,
    "currency": "GBP"
   },
   [
    {
     "maxBasisPoints": 6000,
     "label": "60% LTV"
    },
    {
     "maxBasisPoints": 7500,
     "label": "75% LTV"
    },
    {
     "maxBasisPoints": 8500,
     "label": "85% LTV"
    },
    {
     "maxBasisPoints": 9000,
     "label": "90% LTV"
    },
    {
     "maxBasisPoints": 9500,
     "label": "95% LTV"
    }
   ]
  ],
  "expect": {
   "basisPoints": 7501,
   "band": "85% LTV"
  }
 },
 {
  "name": "\u00a3180,000 on \u00a3300,000 is exactly 60%",
  "args": [
   {
    "minor": 18000000,
    "currency": "GBP"
   },
   {
    "minor": 30000000,
    "currency": "GBP"
   },
   [
    {
     "maxBasisPoints": 6000,
     "label": "60% LTV"
    },
    {
     "maxBasisPoints": 7500,
     "label": "75% LTV"
    },
    {
     "maxBasisPoints": 8500,
     "label": "85% LTV"
    },
    {
     "maxBasisPoints": 9000,
     "label": "90% LTV"
    },
    {
     "maxBasisPoints": 9500,
     "label": "95% LTV"
    }
   ]
  ],
  "expect": {
   "basisPoints": 6000,
   "band": "60% LTV"
  }
 },
 {
  "name": "a small loan is in the lowest band",
  "args": [
   {
    "minor": 5000000,
    "currency": "GBP"
   },
   {
    "minor": 40000000,
    "currency": "GBP"
   },
   [
    {
     "maxBasisPoints": 6000,
     "label": "60% LTV"
    },
    {
     "maxBasisPoints": 7500,
     "label": "75% LTV"
    },
    {
     "maxBasisPoints": 8500,
     "label": "85% LTV"
    },
    {
     "maxBasisPoints": 9000,
     "label": "90% LTV"
    },
    {
     "maxBasisPoints": 9500,
     "label": "95% LTV"
    }
   ]
  ],
  "expect": {
   "basisPoints": 1250,
   "band": "60% LTV"
  }
 },
 {
  "name": "a ratio with a fraction of a basis point rounds up",
  "args": [
   {
    "minor": 10000000,
    "currency": "GBP"
   },
   {
    "minor": 30000000,
    "currency": "GBP"
   },
   [
    {
     "maxBasisPoints": 6000,
     "label": "60% LTV"
    },
    {
     "maxBasisPoints": 7500,
     "label": "75% LTV"
    },
    {
     "maxBasisPoints": 8500,
     "label": "85% LTV"
    },
    {
     "maxBasisPoints": 9000,
     "label": "90% LTV"
    },
    {
     "maxBasisPoints": 9500,
     "label": "95% LTV"
    }
   ]
  ],
  "expect": {
   "basisPoints": 3334,
   "band": "60% LTV"
  }
 },
 {
  "name": "95% exactly",
  "args": [
   {
    "minor": 28500000,
    "currency": "GBP"
   },
   {
    "minor": 30000000,
    "currency": "GBP"
   },
   [
    {
     "maxBasisPoints": 6000,
     "label": "60% LTV"
    },
    {
     "maxBasisPoints": 7500,
     "label": "75% LTV"
    },
    {
     "maxBasisPoints": 8500,
     "label": "85% LTV"
    },
    {
     "maxBasisPoints": 9000,
     "label": "90% LTV"
    },
    {
     "maxBasisPoints": 9500,
     "label": "95% LTV"
    }
   ]
  ],
  "expect": {
   "basisPoints": 9500,
   "band": "95% LTV"
  }
 },
 {
  "name": "above the top band has no band",
  "args": [
   {
    "minor": 29000000,
    "currency": "GBP"
   },
   {
    "minor": 30000000,
    "currency": "GBP"
   },
   [
    {
     "maxBasisPoints": 6000,
     "label": "60% LTV"
    },
    {
     "maxBasisPoints": 7500,
     "label": "75% LTV"
    },
    {
     "maxBasisPoints": 8500,
     "label": "85% LTV"
    },
    {
     "maxBasisPoints": 9000,
     "label": "90% LTV"
    },
    {
     "maxBasisPoints": 9500,
     "label": "95% LTV"
    }
   ]
  ],
  "expect": {
   "basisPoints": 9667,
   "band": null
  }
 },
 {
  "name": "negative equity: more than 100%",
  "args": [
   {
    "minor": 33000000,
    "currency": "GBP"
   },
   {
    "minor": 30000000,
    "currency": "GBP"
   },
   [
    {
     "maxBasisPoints": 6000,
     "label": "60% LTV"
    },
    {
     "maxBasisPoints": 7500,
     "label": "75% LTV"
    },
    {
     "maxBasisPoints": 8500,
     "label": "85% LTV"
    },
    {
     "maxBasisPoints": 9000,
     "label": "90% LTV"
    },
    {
     "maxBasisPoints": 9500,
     "label": "95% LTV"
    }
   ]
  ],
  "expect": {
   "basisPoints": 11000,
   "band": null
  }
 },
 {
  "name": "a zero loan is 0%",
  "args": [
   {
    "minor": 0,
    "currency": "GBP"
   },
   {
    "minor": 30000000,
    "currency": "GBP"
   },
   [
    {
     "maxBasisPoints": 6000,
     "label": "60% LTV"
    },
    {
     "maxBasisPoints": 7500,
     "label": "75% LTV"
    },
    {
     "maxBasisPoints": 8500,
     "label": "85% LTV"
    },
    {
     "maxBasisPoints": 9000,
     "label": "90% LTV"
    },
    {
     "maxBasisPoints": 9500,
     "label": "95% LTV"
    }
   ]
  ],
  "expect": {
   "basisPoints": 0,
   "band": "60% LTV"
  }
 },
 {
  "name": "one band table",
  "args": [
   {
    "minor": 9000000,
    "currency": "GBP"
   },
   {
    "minor": 10000000,
    "currency": "GBP"
   },
   [
    {
     "maxBasisPoints": 10000,
     "label": "all"
    }
   ]
  ],
  "expect": {
   "basisPoints": 9000,
   "band": "all"
  }
 },
 {
  "name": "a zero value is refused",
  "args": [
   {
    "minor": 100,
    "currency": "GBP"
   },
   {
    "minor": 0,
    "currency": "GBP"
   },
   [
    {
     "maxBasisPoints": 6000,
     "label": "60% LTV"
    },
    {
     "maxBasisPoints": 7500,
     "label": "75% LTV"
    },
    {
     "maxBasisPoints": 8500,
     "label": "85% LTV"
    },
    {
     "maxBasisPoints": 9000,
     "label": "90% LTV"
    },
    {
     "maxBasisPoints": 9500,
     "label": "95% LTV"
    }
   ]
  ],
  "expectError": "propertyValue must be greater than zero"
 },
 {
  "name": "a negative loan is refused",
  "args": [
   {
    "minor": -1,
    "currency": "GBP"
   },
   {
    "minor": 100,
    "currency": "GBP"
   },
   [
    {
     "maxBasisPoints": 6000,
     "label": "60% LTV"
    },
    {
     "maxBasisPoints": 7500,
     "label": "75% LTV"
    },
    {
     "maxBasisPoints": 8500,
     "label": "85% LTV"
    },
    {
     "maxBasisPoints": 9000,
     "label": "90% LTV"
    },
    {
     "maxBasisPoints": 9500,
     "label": "95% LTV"
    }
   ]
  ],
  "expectError": "loan must not be negative"
 },
 {
  "name": "an empty band table is refused",
  "args": [
   {
    "minor": 100,
    "currency": "GBP"
   },
   {
    "minor": 1000,
    "currency": "GBP"
   },
   []
  ],
  "expectError": "bands must not be empty"
 },
 {
  "name": "bands out of order are refused",
  "args": [
   {
    "minor": 100,
    "currency": "GBP"
   },
   {
    "minor": 1000,
    "currency": "GBP"
   },
   [
    {
     "maxBasisPoints": 7500,
     "label": "75% LTV"
    },
    {
     "maxBasisPoints": 6000,
     "label": "60% LTV"
    }
   ]
  ],
  "expectError": "strictly ascending"
 },
 {
  "name": "a zero ceiling is refused",
  "args": [
   {
    "minor": 100,
    "currency": "GBP"
   },
   {
    "minor": 1000,
    "currency": "GBP"
   },
   [
    {
     "maxBasisPoints": 0,
     "label": "x"
    }
   ]
  ],
  "expectError": "band ceilings must be whole basis points"
 },
 {
  "name": "mixed currencies are refused",
  "args": [
   {
    "minor": 100,
    "currency": "GBP"
   },
   {
    "minor": 1000,
    "currency": "EUR"
   },
   [
    {
     "maxBasisPoints": 6000,
     "label": "60% LTV"
    },
    {
     "maxBasisPoints": 7500,
     "label": "75% LTV"
    },
    {
     "maxBasisPoints": 8500,
     "label": "85% LTV"
    },
    {
     "maxBasisPoints": 9000,
     "label": "90% LTV"
    },
    {
     "maxBasisPoints": 9500,
     "label": "95% LTV"
    }
   ]
  ],
  "expectError": "currency mismatch"
 },
 {
  "name": "a loan beyond exact arithmetic is refused",
  "args": [
   {
    "minor": 900719925475,
    "currency": "GBP"
   },
   {
    "minor": 1000000000000,
    "currency": "GBP"
   },
   [
    {
     "maxBasisPoints": 6000,
     "label": "60% LTV"
    },
    {
     "maxBasisPoints": 7500,
     "label": "75% LTV"
    },
    {
     "maxBasisPoints": 8500,
     "label": "85% LTV"
    },
    {
     "maxBasisPoints": 9000,
     "label": "90% LTV"
    },
    {
     "maxBasisPoints": 9500,
     "label": "95% LTV"
    }
   ]
  ],
  "expectError": "loan must be at most"
 }
]