Prepended all namespaces with 'cc.journeyman'; tests run, 4 don't pass.

This commit is contained in:
Simon Brooke 2020-11-15 21:09:18 +00:00
parent 37dbb767ac
commit 310896cc95
No known key found for this signature in database
GPG key ID: A7A4F18D1D4DF987
34 changed files with 107 additions and 81 deletions

View file

@ -0,0 +1,109 @@
(ns cc.journeyman.the-great-game.merchants.markets-test
(:require [clojure.test :refer :all]
[cc.journeyman.the-great-game.utils :refer [deep-merge]]
[cc.journeyman.the-great-game.world.world :refer [default-world]]
[cc.journeyman.the-great-game.merchants.markets :refer [adjust-quantity-and-price new-price run]]))
(deftest new-price-test
(testing "Adjustment of prices based on supply and demand"
(is (> (new-price 1 0 10 10) 1)
"If no stock but there is supply and demand, price should rise")
(is (> (new-price 1 0 0 10) 1)
"If no stock but there is demand, price should rise")
(is (> (new-price 1 5 0 10) 1)
"If there is insufficient stock to meet demand, price should rise")
(is (= (new-price 1 10 0 10) 1)
"If there is exactly sufficient stock to meet demand, price should not change")
(is (< (new-price 1 10 0 5) 1)
"If there is surplus stock beyond demand, price should fall")
(is (> (new-price 1 0 0 10) (new-price 1 5 0 10))
"The greater the relative undersupply, the more prices should rise")
(is (< (new-price 1 10 0 0)(new-price 1 10 0 5) 1)
"The greater the relative oversupply, the more prices should fall")
))
(deftest adjust-quantity-and-price-test
(testing "Adjustment in quantity and price: supply only."
(let [world (deep-merge
default-world
{:cities
{:falkirk
{:stock {:iron 0}
:supplies {:iron 12}}}})
actual (adjust-quantity-and-price world :falkirk :iron)]
(is
(=
(-> actual :cities :falkirk :stock :iron)
(-> world :cities :falkirk :supplies :iron))
"If stock is empty it should be topped up by supply amount."))
(let [world (deep-merge
default-world
{:cities
{:falkirk
{:stock {:iron 5}
:supplies {:iron 12}
:prices {:iron 0.9}}}})
actual (adjust-quantity-and-price world :falkirk :iron)]
(is
(=
(-> actual :cities :falkirk :stock :iron)
(-> world :cities :falkirk :supplies :iron))
"If stock is not empty and price is below cost, stock should be topped up only to supply amount."))
(let [world (deep-merge
default-world
{:cities
{:falkirk
{:stock {:iron 5}
:supplies {:iron 12}
:prices {:iron 1.1}}}})
actual (adjust-quantity-and-price world :falkirk :iron)]
(is
(=
(-> actual :cities :falkirk :stock :iron)
(+ (-> world :cities :falkirk :supplies :iron)
(-> world :cities :falkirk :stock :iron)))
"If stock is not empty and price is above cost, stock should be topped up by supply amount.")))
(testing "Adjustment in quantity and price: supply and demand."
(let [world (deep-merge
default-world
{:cities
{:falkirk
{:stock {:iron 10}
:demands {:iron 5}
:supplies {:iron 12}
:prices {:iron 1.1}}}})
actual (adjust-quantity-and-price world :falkirk :iron)]
(is
(=
(-> actual :cities :falkirk :stock :iron)
17)
"Stock should be topped up by the difference between the supply and
the demand amount."))))
(deftest run-test
(let [world (deep-merge
default-world
{:cities
{:aberdeen
{:stock {:fish 5}
:supplies {:fish 12}
:prices {:fish 1.1}}
:falkirk
{:stock {:iron 10}
:demands {:iron 5}
:supplies {:iron 12}
:prices {:iron 1.1}}}})
actual (run world)]
(is
(=
(-> actual :cities :aberdeen :stock :fish)
(+ (-> world :cities :aberdeen :supplies :fish)
(-> world :cities :aberdeen :stock :fish)))
"If stock is not empty and price is above cost, stock should be topped up by supply amount.")
(is
(=
(-> actual :cities :falkirk :stock :iron)
17)
"Stock should be topped up by the difference between the supply and
the demand amount.")))

View file

@ -0,0 +1,128 @@
(ns cc.journeyman.the-great-game.merchants.merchant-utils-test
(:require [clojure.test :refer :all]
[cc.journeyman.the-great-game.utils :refer [deep-merge]]
[cc.journeyman.the-great-game.world.world :refer [default-world]]
[cc.journeyman.the-great-game.merchants.merchant-utils :refer
[add-stock burden can-afford can-carry expected-price]]))
(deftest expected-price-test
(testing "Anticipated prices in markets"
(let [world (deep-merge
default-world
{:merchants
{:archie
{:known-prices
{:buckie
{:iron
[{:price 1.7 :date 1}
{:price 2 :date 0}]}}}}})]
(let [actual (expected-price (-> world :merchants :archie) :fish :edinburgh)
expected 1] ;;
(is (= actual expected) "if no information assume 1"))
(let [actual (expected-price (-> world :merchants :archie) :iron :buckie)
expected 1.7] ;;
(is (= actual expected) "if information select the most recent")))))
(deftest burden-test
(testing "Burden of merchant"
(let [world (deep-merge
default-world
{:merchants
{:archie
{:stock
{:iron 1}}
:belinda
{:stock
{:fish 2}}
:callum
{:stock
{:iron 1
:fish 1}}}})]
(let [actual (burden :archie world)
expected (-> world :commodities :iron :weight)]
(is (= actual expected)))
(let [actual (burden :belinda world)
expected (* 2 (-> world :commodities :fish :weight))]
(is (= actual expected)))
(let [actual (burden :callum world)
expected (+
(-> world :commodities :iron :weight)
(-> world :commodities :fish :weight))]
(is (= actual expected)))
(let [actual (burden {} world)
expected 0]
(is (= actual expected)))
(let [actual (burden (-> world :merchants :deidre) world)
expected 0]
(is (= actual expected))))))
(deftest can-carry-test
(testing "What merchants can carry"
(let [world (deep-merge
default-world
{:merchants
{:archie
{:cash 5
:stock
{:iron 1}}
:belinda
{:stock
{:fish 2}}
:callum
{:stock
{:iron 1
:fish 1}}}})]
(let [actual (can-carry :archie world :fish)
expected 0]
(is (= actual expected)))
(let [actual (can-carry :belinda world :fish)
expected 8]
(is (= actual expected)))
(let [actual (can-carry (-> world :merchants :archie) world :fish)
expected 0]
(is (= actual expected)))
(let [actual (can-carry {:stock {:fish 7} :capacity 10} world :fish)
expected 3]
(is (= actual expected))))))
(deftest affordability-test
(testing "What merchants can afford to purchase"
(let [world (deep-merge
default-world
{:merchants
{:archie
{:cash 5
:stock
{:iron 1}}
:belinda
{:stock
{:fish 2}}
:callum
{:stock
{:iron 1
:fish 1}}}})]
(let [actual (can-afford :archie world :fish)
expected 5]
(is (= actual expected)))
(let [actual (can-afford :belinda world :fish)
expected 100]
(is (= actual expected)))
(let [actual (can-afford (-> world :merchants :archie) world :fish)
expected 5]
(is (= actual expected)))
(let [actual (can-afford {:cash 3 :location :buckie} world :fish)
expected 3]
(is (= actual expected)))
(is (thrown-with-msg?
Exception
#"No merchant?"
(can-afford :no-one world :fish)))
(is (thrown-with-msg?
Exception
#"No known location for merchant.*"
(can-afford {:cash 3} world :fish))))))
(deftest add-stock-test
(let [actual (add-stock {:iron 2 :fish 5} {:fish 3 :whisky 7})
expected {:iron 2 :fish 8 :whisky 7}]))

View file

@ -0,0 +1,92 @@
(ns cc.journeyman.the-great-game.merchants.planning-test
(:require [clojure.test :refer :all]
[cc.journeyman.the-great-game.utils :refer [deep-merge]]
[cc.journeyman.the-great-game.world.world :refer [default-world]]
[cc.journeyman.the-great-game.merchants.planning :refer [plan-trade select-cargo]]))
(deftest plan-trade-test
(testing "Lower level trade planning"
(let [world (deep-merge
default-world
{:merchants
{:fiona
{:known-prices
{:aberdeen
{:iron
[{:price 1.5 :date 1}
{:price 1.3 :date 0}]}
:buckie
{:iron
[{:price 1.7 :date 1}
{:price 2 :date 0}]}}}}
:cities
{:falkirk
{:stock {:iron 20}}}})
actual (plan-trade :fiona world :iron)]
(is (= (:origin actual) :falkirk)
"Fiona is in Falkirk, so her plan must originate there")
(is (= (:commodity actual) :iron)
"Iron is the only thing available in Falkirk, so plan must carry iron")
(is (= (:destination actual) :buckie)
"Fiona believes Buckie offers the best price for iron, so should go there"))))
(deftest select-cargo-test
(testing "Top level single trade planning: single candidate commodity"
(let [world (deep-merge
default-world
{:merchants
{:fiona
{:known-prices
{:aberdeen
{:iron
[{:price 1.5 :date 1}
{:price 1.3 :date 0}]}
:buckie
{:iron
[{:price 1.7 :date 1}
{:price 2 :date 0}]}}}}
:cities
{:falkirk
{:stock {:iron 20}}}})
actual (select-cargo :fiona world)]
(is (= (:origin actual) :falkirk)
"Fiona is in Falkirk, so her plan must originate there")
(is (= (:commodity actual) :iron)
"Iron is the only thing available in Falkirk, so plan must carry iron")
(is (= (:destination actual) :buckie)
"Fiona believes Buckie offers the best price for iron, so should go there")
(is (= (:quantity actual) 1)
"Fiona can carry only one unit of iron.")
(is (= (:expected-profit actual) 0.7))))
(testing "Top level single trade planning: multiple candidate commodities"
(let [world (deep-merge
default-world
{:merchants
{:fiona
{:known-prices
{:aberdeen
{:iron
[{:price 1.5 :date 1}
{:price 1.3 :date 0}]
:whisky [{:price 4 :date 0}]}
:buckie
{:iron
[{:price 1.7 :date 1}
{:price 2 :date 0}]}}}}
:cities
{:falkirk
{:stock
{:iron 20
:whisky 50}}}})
actual (select-cargo :fiona world)]
(is (= (:origin actual) :falkirk)
"Fiona is in Falkirk, so her plan must originate there")
(is (= (:commodity actual) :whisky)
"Whisky has the higher profit, so plan must carry whisky")
(is (= (:destination actual) :aberdeen)
"Fiona believes Aberdeen offers the best price for whisky, so should go there")
(is (= (:quantity actual) 50)
"Fiona can carry 100 units of whisky, but only 50 are available.")
(is (= (:expected-profit actual) 150)))))