Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Demonstration of how test.check works. Generative testing in Clojure
(ns secland.compount-interest-test
(:require [clojure.spec.alpha :as s]
[clojure.test.check.clojure-test :refer [defspec]]
[clojure.test.check.generators :as gen]
[ :as prop]
[secland.finances.compound-interest :as comp-interest]))
(defn- define-rate-range [min max]
(gen/fmap #(BigDecimal. (/ % 1000.)) (gen/large-integer* {:min min :max max})))
(def generator-interest-type
(gen/let [conv-type (gen/elements (vec (s/describe ::comp-interest/type)))
rate-values (case conv-type
:month->year (define-rate-range 1 150)
:month->day (define-rate-range 1 150)
:year->month (define-rate-range 10 4000)
:day->year (define-rate-range 1 4)
:year->day (define-rate-range 10 4000)
:day->month (define-rate-range 1 4))
base (gen/elements (vec (s/describe ::comp-interest/base)))
precision (gen/large-integer* {:min 2 :max 20})]
{:base base
:type conv-type
:rate rate-values
:precision precision}))
(defn find-the-reverse-operation [operation-type]
(operation-type {:month->year :year->month
:month->day :day->month
:year->month :month->year
:day->year :year->day
:year->day :day->year
:day->month :month->day}))
(defspec conversion-to-interest-rates 1000
(prop/for-all [interest-type generator-interest-type]
(let [interest-rate-forward (comp-interest/converter interest-type)
interest-rate-backward (comp-interest/converter (assoc interest-type
:type (find-the-reverse-operation (:type interest-type))
:rate interest-rate-forward))]
(.equals interest-rate-backward (:rate interest-type))
(decimal? interest-rate-forward)
(= (.scale interest-rate-forward) (:precision interest-type)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment