I started the kata in a Barcelona Clojure Developers event.
The truth is that, since I was learning how to use the Component library, I didn't use TDD.
Instead I worked on the REPL to get everything in place and make it work.
Then I wrote the tests I would have liked to write if I had used outside-in TDD with Midje.
I find that, when I'm learning something new, it works better for me what Brian Marick describes in these tweets:
Now I'll show you the tests I actually wrote afterwards, in the order I would have written them doing outside-in TDD.(6) the immediately-following writing of tests to capture what I've learned counts as Schön-style reflection on just-prior practice.
— Brian Marick (@marick) July 26, 2016
This is the acceptance test I would have started with:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns bank-account.acceptance-test | |
(:require | |
[midje.sweet :refer :all] | |
[bank-account.test-helpers :refer [output-lines make-dates]] | |
[com.stuartsierra.component :as component] | |
[bank-account.factories :as factories] | |
[bank-account.account :as account])) | |
(unfinished date-fn) | |
(facts | |
"printing an account statement" | |
(let [config {:format {:date-format "dd/MM/yyyy" | |
:separator "||" | |
:num-decimals 2 | |
:header "date || credit || debit || balance"}} | |
dates (partial make-dates "dd/MM/yyyy") | |
account-system (assoc (factories/make-system config) | |
:transactions | |
(factories/in-memory-transactions #(date-fn))) | |
account (-> account-system component/start :account)] | |
(do | |
(account/deposit! account 1000) | |
(account/deposit! account 2000) | |
(account/withdraw! account 500) | |
(output-lines | |
account/print-statement account)) | |
=> ["date || credit || debit || balance" | |
"14/01/2012 || || 500.00 || 2500.00" | |
"13/01/2012 || 2000.00 || || 3000.00" | |
"10/01/2012 || 1000.00 || || 1000.00"] | |
(provided | |
(date-fn) =streams=> (dates ["10/01/2012" "13/01/2012" "14/01/2012"])))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns bank-account.account-test | |
(:require | |
[midje.sweet :refer :all] | |
[midje.open-protocols :refer [defrecord-openly]] | |
[com.stuartsierra.component :as component] | |
[bank-account.account :as account] | |
[bank-account.factories :as factories] | |
[bank-account.transactions-operations.transactions-operations :as transactions-operations] | |
[bank-account.statement-printing.statement-printer :as statement-printer])) | |
(unfinished register!) | |
(unfinished balanced-transactions) | |
(unfinished print-statement) | |
(defrecord-openly FakeTransactions [] | |
transactions-operations/TransactionsOperations | |
(register! [this amount]) | |
(balanced-transactions [this])) | |
(defrecord-openly FakePrinter [] | |
statement-printer/StatementPrinter | |
(print-statement [this balanced-transactions])) | |
(defn new-account [transactions printer] | |
(-> (factories/account) | |
(merge {:transactions transactions | |
:printer printer}) | |
component/start)) | |
(facts | |
"about account operations" | |
(fact | |
"it registers deposit transactions" | |
(let [fake-transactions (->FakeTransactions) | |
an-account (new-account fake-transactions :not-used)] | |
(account/deposit! an-account 50) => irrelevant | |
(provided | |
(register! fake-transactions 50) => irrelevant :times 1))) | |
(fact | |
"it registers withdrawals transactions" | |
(let [fake-transactions (->FakeTransactions) | |
an-account (new-account fake-transactions :not-used)] | |
(account/withdraw! an-account 100) => irrelevant | |
(provided | |
(register! fake-transactions -100) => irrelevant :times 1))) | |
(fact | |
"it prints the transactions in the statement" | |
(let [fake-transactions (->FakeTransactions) | |
fake-printer (->FakePrinter) | |
an-account (new-account fake-transactions fake-printer)] | |
(account/print-statement an-account) => irrelevant | |
(provided | |
(balanced-transactions | |
fake-transactions) => ...some-balanced-transactions... :times 1 | |
(print-statement | |
fake-printer | |
...some-balanced-transactions...) => irrelevant :times 1)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns bank-account.in-memory-transactions-test | |
(:require | |
[midje.sweet :refer :all] | |
[midje.open-protocols :refer [defrecord-openly]] | |
[com.stuartsierra.component :as component] | |
[bank-account.factories :as factories] | |
[bank-account.transactions-operations.transactions-operations :as transactions] | |
[bank-account.test-helpers :refer [make-date]])) | |
(unfinished date-fn) | |
(defn new-in-memory-transactions [date-fn] | |
(component/start (factories/in-memory-transactions date-fn))) | |
(fact | |
"about transactions" | |
(facts | |
"in memory" | |
(fact | |
"returns balanced transactions lines for all registered transactions" | |
(let [date (partial make-date "dd/MM/yyyy") | |
first-transaction {:amount 1000 :date (date "10/02/2016")} | |
second-transaction {:amount 1500 :date (date "13/05/2016")} | |
third-transaction {:amount -500 :date (date "14/08/2016")} | |
in-memory-transactions (new-in-memory-transactions #(date-fn))] | |
(do | |
(transactions/register! in-memory-transactions (:amount first-transaction)) | |
(transactions/register! in-memory-transactions (:amount second-transaction)) | |
(transactions/register! in-memory-transactions (:amount third-transaction)) | |
(transactions/balanced-transactions in-memory-transactions)) | |
=> [(assoc first-transaction :balance 1000) | |
(assoc second-transaction :balance 2500) | |
(assoc third-transaction :balance 2000)] | |
(provided (date-fn) =streams=> [(:date first-transaction) | |
(:date second-transaction) | |
(:date third-transaction)]))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns bank-account.console-statement-printer-test | |
(:require | |
[midje.sweet :refer :all] | |
[midje.open-protocols :refer [defrecord-openly]] | |
[com.stuartsierra.component :as component] | |
[bank-account.factories :as factories] | |
[bank-account.statement-formatting.statement-format :refer [StatementFormat]] | |
[bank-account.statement-printing.statement-printer :as printer] | |
[bank-account.test-helpers :refer [output-lines]])) | |
(unfinished format-statement-lines) | |
(unfinished header) | |
(defrecord-openly FakeFormat [] | |
StatementFormat | |
(header [this]) | |
(format-statement-lines [this statement-lines])) | |
(defn new-console-printer | |
([format print-fn] | |
(component/start (merge (factories/console-printer) | |
{:format format | |
:print-fn print-fn}))) | |
([format] | |
(new-console-printer format identity))) | |
(fact | |
"about printing statements" | |
(fact | |
"it asks the format for the header" | |
(let [fake-format (->FakeFormat) | |
a-printer (new-console-printer fake-format)] | |
(printer/print-statement | |
a-printer :not-used-in-this-test) => irrelevant | |
(provided | |
(header fake-format) => irrelevant :times 1))) | |
(fact | |
"it asks the format to format all balanced transactions" | |
(let [fake-format (->FakeFormat) | |
a-printer (new-console-printer fake-format)] | |
(printer/print-statement | |
a-printer | |
...some-balanced-transactions...) => irrelevant | |
(provided | |
(format-statement-lines | |
fake-format | |
...some-balanced-transactions...) | |
=> ...some-formatted-statement-lines... :times 1))) | |
(fact | |
"it prints the header and formatted lines" | |
(let [some-header "some-header" | |
some-formatted-statement-lines ["statement-line-1" "statement-line-2"] | |
expected-output-lines (cons some-header some-formatted-statement-lines) | |
fake-format (->FakeFormat) | |
a-printer (new-console-printer fake-format println)] | |
(output-lines | |
printer/print-statement | |
a-printer | |
...some-balanced-transactions...) => expected-output-lines | |
(provided | |
(header fake-format) => some-header | |
(format-statement-lines | |
fake-format | |
...some-balanced-transactions...) => some-formatted-statement-lines)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns bank-account.nice-reverse-statement-format-test | |
(:require | |
[midje.sweet :refer :all] | |
[midje.open-protocols :refer [defrecord-openly]] | |
[com.stuartsierra.component :as component] | |
[bank-account.factories :as factories] | |
[bank-account.statement-formatting.statement-format :as statement-format] | |
[bank-account.test-helpers :refer [make-date]])) | |
(defn- new-nice-reverse-format [config] | |
(component/start (factories/nice-reverse-statement-format config))) | |
(fact | |
"about formatting statements" | |
(facts | |
"using NiceReverseStatementFormat" | |
(let [config {:date-format "dd/MM/yyyy" | |
:separator "||" | |
:num-decimals 2 | |
:header "date || credit || debit || balance"} | |
date (partial make-date (:date-format config)) | |
nice-reverse-format (new-nice-reverse-format config)] | |
(fact | |
"it returns the configured header" | |
(statement-format/header nice-reverse-format) => (:header config)) | |
(fact | |
"it formats the statement lines" | |
(let [balanced-transactions [{:balance 1000 :amount 1000 :date (date "10/02/2016")} | |
{:balance 2500 :amount 1500 :date (date "13/05/2016")} | |
{:balance 2000 :amount -500 :date (date "14/08/2016")}]] | |
(statement-format/format-statement-lines | |
nice-reverse-format | |
balanced-transactions) | |
=> ["14/08/2016 || || 500.00 || 2000.00" | |
"13/05/2016 || 1500.00 || || 2500.00" | |
"10/02/2016 || 1000.00 || || 1000.00"]))))) |
Doing this kata I learned and practiced how to use Component.
I also learned how to use Midje's defrecord-openly and provided macros to mock protocols which helped me correct something I did wrong in another kata.
No comments:
Post a Comment