Added lots of unit tests, all of which pass. But the core program still

breaks!
This commit is contained in:
simon 2014-03-27 08:19:13 +00:00
parent 0290045971
commit 0e0c226eea
3 changed files with 101 additions and 27 deletions

View file

@ -9,13 +9,13 @@
:change nil
:output nil} )
(def coin-values {:merk 1 :plack 0.25 :bawbee 0.10 :bodle 0.05})
(def coin-values {:merk 100 :plack 25 :bawbee 10 :bodle 5})
(keys coin-values)
(.indexOf (keys coin-values) :bodle)
(def item-prices {:caramel-wafer 0.65 :teacake 1 :snowball 1.5})
(def item-prices {:caramel-wafer 65 :teacake 100 :snowball 150})
(defn coin-value [coin]
(coin-values coin))
@ -65,6 +65,8 @@
(defn subtract-denomination [list position]
"given a list of four numbers and a position, return a similar list with one subtracted
from the number at this position in the list"
(cond (= (count list) position)(cons (- (first list) 1) (rest list))
true (cons (first list) (subtract-denomination (rest list) position))))
@ -103,26 +105,29 @@
(apply in-make-change (map #(or % 0) (list amount merk plack bawbee bodle)))
))
(defn subtract-change [machine item-price change]
"subtract this change from this machine and return the machine"
(let [coins (:coins machine)
merk (:merk coins)
plack (:plack coins)
bawbee (:bawbee coins)
bodle (:bodle coins)
chance (make-change item-price merk plack bawbee bodle)])
(assoc (dissoc machine :change) :change change))
(defn make-change-machine [machine item-price change]
(let [
tend (sum-coins (:tendered machine))
change (make-change item-price (:merk tend) (:plack tend) (:bawbee tend) (:bodle tend))]
(cond (nil? change) machine)
true (assoc (dissoc (subtract-change machine item-price change) :change ) :change change )))
(defn subtract-change [coin-stacks change]
"Return a copy of these coin-stacks with this change removed"
{:merk (- (:merk coin-stacks) (nth change 0))
:plack (- (:plack coin-stacks) (nth change 1))
:bawbee (- (:bawbee coin-stacks) (nth change 2))
:bodle (- (:bodle coin-stacks) (nth change 3))})
(defn subtract-change-machine [machine change]
"return a copy of this machine which has this amount of change removed from its coins"
(let [coins (:coins machine)]
(assoc (dissoc machine :coins) :coins (subtract-change coins change))))
(defn make-change-machine [machine change]
"given this machine and these numbers of coins to remove, return a copy of the machine
with the coins removed"
(let [tend (sum-coins (:tendered machine))]
(cond (= change '(0 0 0 0)) machine)
true (assoc (dissoc (subtract-change-machine machine change) :change ) :change change )))
(defn remove-from-stock [machine item]
"TODO: This requires clever use of update-in"
machine)
"return a copy of this machine with one fewer of this item in stock"
(update-in machine [:items item] dec))
(defn deliver-item [machine item change]
(make-change-machine
@ -135,12 +140,14 @@
(defn get-item [machine item]
(let [item-price (item item-prices)
tend (sum-coins (:tendered machine))
change (make-change item-price (:merk tend) (:plack tend) (:bawbee tend) (:bodle tend))]
(cond (>= 0 (item (:stock machine))) (message-machine (coin-return machine) (str "Sorry, " item " not in stock"))
(<= (coins-value (:tendered machine)) item-price) (message-machine machine "Please insert more money")
(empty? change) (message-machine (coin-return machine) "Sorry, I don't have enough change.")
true (message-machine (deliver-item machine item change) (str "Enjoy your " item)))))
coins (:coins machine)
tendered (coins-value (:tendered machine))
change (make-change (- tendered item-price) (:merk coins) (:plack coins) (:bawbee coins) (:bodle coins))]
(print change)
(cond (>= 0 (item (:stock machine))) (message-machine (coin-return machine) (str "Sorry, " item " not in stock"))
(<= tendered item-price) (message-machine machine "Please insert more money")
(= change '(0 0 0 0)) (message-machine (coin-return machine) "Sorry, I don't have enough change.")
true (message-machine (deliver-item machine item change) (str "Enjoy your " item)))))
(defn get-caramel-wafer [machine]
(get-item machine :caramel-wafer))

View file

@ -0,0 +1,68 @@
(ns vending.test.core
(:use clojure.test
ring.mock.request
vending.core))
(defn member?
"true if seq contains elm"
[seq elm]
(some #(= elm %) seq))
(deftest test-add-coin
(testing
"Test adding coins to machine"
(let [machine (make-default-machine)
merk-machine (add-coin machine :merk)
plack-machine (add-coin machine :plack)
bawbee-machine (add-coin machine :bawbee)
bodle-machine (add-coin machine :bodle)
all-machine (add-coin (add-coin (add-coin (add-coin machine :merk) :plack) :bawbee) :bodle) ]
(is (member? (:tendered merk-machine) :merk) "after adding a merk, a merk should be present")
(is (member? (:tendered all-machine) :merk) "after adding a merk, a merk should be present")
(is (member? (:tendered plack-machine) :plack) "after adding a plack, a plack should be present")
(is (member? (:tendered all-machine) :plack) "after adding a plack, a plack should be present")
(is (member? (:tendered bawbee-machine) :bawbee) "after adding a bawbee, a bawbee should be present")
(is (member? (:tendered all-machine) :bawbee) "after adding a bawbee, a bawbee should be present")
(is (member? (:tendered bodle-machine) :bodle) "after adding a bodle, a bodle should be present")
(is (member? (:tendered all-machine) :bodle) "after adding a merk, a merk should be present")
(is (nil? (:tendered machine)) "No coins should leak through into the base machine")))
(testing
"coin-return should return all coins added"
(let [machine (make-default-machine)
all-machine (add-coin (add-coin (add-coin (add-coin machine :merk) :plack) :bawbee) :bodle)
return-machine (coin-return all-machine)]
(is (= (:message return-machine)) "Coins returned")
(is (= (:tendered all-machine) (:change return-machine)) "All coins should be returned")
))
(testing
"summing coins"
(let [coins1 (sum-coins (list :merk :plack :bawbee :bodle))
coins2 (sum-coins (list :merk :plack :bawbee :bodle :merk :plack :bawbee :bodle))]
(= (:merk coins1 1) "after adding one merk, one merk should be present")
(= (:merk coins2 2) "after adding two merks, two merks should be present")
))
(testing
"making appropriate change"
(let [no-change (make-change 0 5 5 5 5)
ten-change (make-change 10 5 5 5 5)
all-change (make-change 140 5 5 5 5)]
(is (= no-change '(0 0 0 0)) "one hundred units of change should be satisfied with one merk")
(is (= all-change '(1 1 1 1)) "140 units of change should be satisfied with one coin of each denomination")
(is (or (= ten-change '(0 0 1 0)) (= ten-change '(0 0 0 2))) "ten change could be satisfied with one bawbee or two bodles")))
(testing
"removing change from machine"
(let [machine (make-default-machine)
changed (make-change-machine machine '(1 1 1 1))
emptied (make-change-machine machine '(1 4 4 4))]
(is (= (vals (:coins changed)) '(0 3 3 3)) "each coin slot should be decremented by one")
(is (= (vals (:coins emptied)) '(0 0 0 0)) "each coin slot should be empty (contain zero)")
))
)
(make-change-machine (make-default-machine) '( 1 1 1 1))

View file

@ -7,8 +7,7 @@
(testing "main route"
(let [response (app (request :get "/"))]
(is (= (:status response) 200))
(is (= (:body response)
"<html>\n <head>\n <title>Welcome to vending</title>\n <link href=\"/css/screen.css\" rel=\"stylesheet\" type=\"text/css\"></link>\n </head>\n <body>\n <div class=\"navbar navbar-fixed-top navbar-inverse\">\n <ul class=\"nav\">\n <li>\n <a href=\"/\">Home</a>\n </li>\n <li>\n <a href=\"/about\">About</a>\n </li>\n </ul>\n </div>\n <div id=\"content\">\n <h1>Welcome to vending</h1>\n \n<h2>Some links to get started</h2><ol><li><a href='http://www.luminusweb.net/docs/html&#95;templating.md'>HTML templating</a></li><li><a href='http://www.luminusweb.net/docs/database.md'>Accessing the database</a></li><li><a href='http://www.luminusweb.net/docs/static&#95;resources.md'>Serving static resources</a></li><li><a href='http://www.luminusweb.net/docs/responses.md'>Setting response types</a></li><li><a href='http://www.luminusweb.net/docs/routes.md'>Defining routes</a></li><li><a href='http://www.luminusweb.net/docs/middleware.md'>Adding middleware</a></li><li><a href='http://www.luminusweb.net/docs/sessions&#95;cookies.md'>Sessions and cookies</a></li><li><a href='http://www.luminusweb.net/docs/security.md'>Security</a></li><li><a href='http://www.luminusweb.net/docs/deployment.md'>Deploying the application</a></li></ol>\n\n </div> \n <footer>Copyright ...</footer>\n </body>\n</html>\n\n\n"))))
))
(testing "not-found route"
(let [response (app (request :get "/invalid"))]