-
Notifications
You must be signed in to change notification settings - Fork 631
[CBR-371] unit tests for listing addresses #3563
Conversation
f271f03
to
19598e6
Compare
082addd
to
ad0938d
Compare
9762820
to
4330112
Compare
4330112
to
de5d4db
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job @kderme ! We are getting there, but I think we can do slightly better in the code design space. I have jotted down some ideas. Let me know what you think!
db <- Kernel.getWalletSnapshot pw | ||
let Right accs = Accounts.getAccounts (V1.walId v1Wallet) db | ||
let accounts = IxSet.toList accs | ||
length accounts `shouldBe` (acn + 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend flipping the logic and doing something like:
prepareAddressFixture acn adn =
-- We recompute the values to account for the fact that creating a new wallet
-- @always@ come with a fresh account, and this account always have a fresh address
-- associated with it.
let requestedAccounts = max 0 (acn - 1)
let requestedAddresses = max 0 (adn - 1)
Then, you can use those two let bindings all over the place without having to worry about +1/-1 arithmetic, both in the fixtures and in the tests. Furthermore, you segregate the comment on why we do this exactly in one point in the code, without this assumption being scattered all over the place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand what are the semantics of requestedAddresses
. Some accounts will have requestedAddresses addresses, while the first account will have requestedAddresses+1. Also requestedAccounts should never be 0, as one account is created by default.
return $ M.fromList res | ||
|
||
expectedNumber :: Int -> Int -> Int | ||
expectedNumber acc adr = (acc + 1)*(adr + 1) - acc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if you bake the logic inside the fixture, you might be able to remove this.
Right wr -> do | ||
-- this takes into account that there is an initial account | ||
-- and each account has an initial address (but not the initial | ||
-- account thus the -1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, unfortunately if you create multiple accounts for the same wallet those won't come with an extra associated address. But ideally, if you can bake this inside the fixture creation, test logic should hopefully simplify 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should delete this comment.
let pp = PaginationParams (Page 1) (PerPage 40) | ||
let pp1 = PaginationParams (Page 1) (PerPage (quot expectedTotal 3 + 1)) | ||
let pp2 = PaginationParams (Page 2) (PerPage (quot expectedTotal 3 + 1)) | ||
let pp3 = PaginationParams (Page 3) (PerPage (quot expectedTotal 3 + 1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit dense for the reader to try to figure out why you do the quot expectedTotal
dance, but hopefully we can simplify this one.
res `shouldBe` res' | ||
res1 `shouldBe` res1' | ||
res2 `shouldBe` res2' | ||
res3 `shouldBe` res3' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Idea: considering is very error prone to go for this style of foo, foo', bar, bar'
, why don't you write something like this?
res <- runExceptT $ runHandler' $ do
r1 <- Handlers.listAddresses layer (RequestParams pp)
r2 <- Handlers.listAddresses layer (RequestParams pp)
pure (r1 === r2)
res1 <- runExceptT $ runHandler' $ do
r1 <- Handlers.listAddresses layer (RequestParams pp1)
r2 <- Handlers.listAddresses layer (RequestParams pp1)
pure (r1 === r2)
assert $ conjoin [res, res1]
Even better, I think you can simplify this even further by noticing how this is just iterating over [pp,pp1,pp2,pp3] but executing mechanical actions, so you can write something which runs a forM
, calls internally replicateM 2
, yields a Property
and conjoin everything at the end.
S.fromList con `shouldBe` S.fromList (wrData wr) | ||
(addrRoot . V1.unV1 . V1.addrId <$> con) | ||
`shouldBe` (addrRoot . V1.unV1 . V1.addrId <$> wrData wr) | ||
_ -> fail ("Got " ++ show res) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a minor thing, but these tests feels very imperative rather than declarative. I don't know what we can do about it, but I suspect we might come up with some combinators which factor away duplication and mechanical reshuffling of the data and leave the logic of the tests exposes. I guess what we aim is something like:
myTest = do
-- Initialisation
-- Execution
-- Checking of properties
Which is exactly what your tests are also doing, but each of these steps takes a lot of lines of code and is hard to track down the spirit of the test 😉
We discussed this with @kderme , and we agreed he will open a separate ticket for the cleanup as requested by my original review. |
cleanup ticket at https://iohk.myjetbrains.com/youtrack/issue/CBR-435 |
[CBR-371] unit tests for listing addresses
…hk/kderme/CBR-371 [CBR-371] unit tests for listing addresses
Description
This PR adds tests for listing addresses:
UPDATE: a very small bug affected pagination when there are multiple accounts (see the diff in wallet-new/src/Cardano/Wallet/WalletLayer/Kernel/Addresses.hs). Now order is consistent always.
Linked issue
https://iohk.myjetbrains.com/youtrack/issue/CBR-371
Type of change
Developer checklist
Testing checklist
QA Steps
Screenshots (if available)