(ns book.exchange-test (:import [book.PersistentSortedList]) (:require [midje.sweet :refer :all] [book.exchange :refer :all] [book.match :refer [create-buy-book create-sell-book]])) (def PersistentSortedList? (comp #(= % book.PersistentSortedList) type)) (facts "the exchange as an whole" (fact "process-sell-order should work when book empty" (let [book empty-book order {:type :sell :quantity 10 :price 2 :book.order/id 1} expt-new-sell-book [order] [{new-sell-book :sell new-buy-book :buy} new-order new-trades] (process-sell-order book order)] new-sell-book => expt-new-sell-book new-buy-book => empty? new-order => order new-trades => empty?)) (fact "process-sell-order should work when there is a buy order that matches" (let [sell-book (create-sell-book) buy-book (create-buy-book {:type :buy :quantity 10 :price 3 :book.order/id 2}) book {:sell sell-book :buy buy-book} order {:type :sell :quantity 4 :price 2 :book.order/id 3} expt-new-buy-book [{:price 3 :quantity 6 :type :buy :book.order/id 2}] expt-new-trades [#:book.order{:book-id 2 :order-id 3 :price 3 :quantity 4 :type :buy}] [{new-sell-book :sell new-buy-book :buy} new-order new-trades] (process-order book order)] new-sell-book => empty? new-buy-book => expt-new-buy-book new-order => nil? new-trades => expt-new-trades)) (fact "process-buy-order should work when book empty" (let [book empty-book order {:type :buy :quantity 10 :price 2 :book.order/id 1} expt-new-sell-book [order] [{new-sell-book :sell new-buy-book :buy} new-order new-trades] (process-order book order)] new-sell-book => empty? new-buy-book => expt-new-sell-book new-order => order new-trades => empty?)) (fact "process-buy-order should work when there is a buy order that matches" (let [sell-book (create-sell-book {:type :sell :quantity 10 :price 3 :book.order/id 2}) buy-book (create-buy-book) book {:sell sell-book :buy buy-book} order {:type :buy :quantity 4 :price 4 :book.order/id 3} expt-new-sell-book [{:price 3 :quantity 6 :type :sell :book.order/id 2}] expt-new-trades [#:book.order{:book-id 2 :order-id 3 :price 3 :quantity 4 :type :sell}] [{new-sell-book :sell new-buy-book :buy} new-order new-trades] (process-order book order)] new-sell-book => expt-new-sell-book new-order => nil? new-trades => expt-new-trades)) (fact "process-order total dance" (let [book empty-book order-1 {:type :buy :quantity 10 :price 100 :book.order/id 7} order-2 {:type :buy :quantity 15 :price 99 :book.order/id 8} order-3 {:type :sell :quantity 17 :price 99 :book.order/id 9} order-4 {:type :sell :quantity 1 :price 102 :book.order/id 10} expt-book-4 {:buy [{:price 99 :quantity 8 :type :buy :book.order/id 8}] :sell [{:price 102 :quantity 1 :type :sell :book.order/id 10}]} [book-1 _ _] (process-order book order-1) [book-2 _ _] (process-order book-1 order-2) [book-3 _ _] (process-order book-2 order-3) [book-4 _ _] (process-order book-3 order-4)] book-4 => expt-book-4)))