Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add assertAmountsEqual() helper #2453

Merged
merged 5 commits into from
Mar 29, 2021
Merged

Conversation

Chris-Hibbert
Copy link
Contributor

closes: #2442

@Chris-Hibbert Chris-Hibbert self-assigned this Feb 17, 2021
@Chris-Hibbert Chris-Hibbert added enhancement New feature or request hygiene Tidying up around the house Small test labels Feb 17, 2021
@Chris-Hibbert Chris-Hibbert added this to the Beta Launch milestone Feb 17, 2021
Copy link
Contributor

@katelynsills katelynsills left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I think this effort might have to wait until after the amountMath refactoring. Here's why:

The function as written will pass even if the "amounts" aren't equal! See the zcf.makeInvitation - no customProperties test in test-zcf.js for an example of something passing when it shouldn't be. Even if we added more checks (such as .brand !== undefined) I think that would be the wrong solution. I think we actually want to use amountMath.isEqual to get the real, robust, and canonical answer on whether the two are equal. That will save us from any errors in trying to replicate it. (Of course, if we want to add other checks after it fails to provide a better error message we can. My worry is that we will have passes when we should have failures.)

But now, that means that we have to pass in an amountMath, which is difficult and annoying. I tried doing this, and I don't recommend it. However, after the amountMath refactoring, we won't need to.

So, I think this PR is the best that we could do now, but I think it's risky and I would probably prefer to redo it after the amountMath refactoring.

@@ -302,7 +303,7 @@ test(`zcf.makeInvitation - no customProperties`, async t => {
// https://github.com/Agoric/agoric-sdk/issues/1705
// @ts-ignore
const details = await E(zoe).getInvitationDetails(invitationP);
t.deepEqual(details, {
assertAmountsEqual(t, details, {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh no, this is passing but it shouldn't. This is a record, not an amount, so when assertAmountsEqual checks .brand and .value both are undefined, and undefined === undefined so this passes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, even if these were amounts, we should ensure this fails because MathKind.SET wasn't passed in, so MathKind.NAT was used as the default, and that is wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted this incorrect conversion fo deepEqual() to assertAmountsEqual(). I'll convert the PR to draft until we have a solution for AmountMaths.

blocked on: #2311

@Chris-Hibbert Chris-Hibbert marked this pull request as draft February 17, 2021 17:19
@katelynsills
Copy link
Contributor

Hey @Chris-Hibbert, now that the new amountMath is in, we can revisit this!

@rowgraus rowgraus removed this from the Beta Initial Launch milestone Mar 29, 2021
@Chris-Hibbert Chris-Hibbert marked this pull request as ready for review March 29, 2021 20:34
Copy link
Contributor

@katelynsills katelynsills left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should never have to pass a MathKind in to know whether two amounts are equal. We should change this API

t,
amount,
expected,
mathKind = MathKind.NAT,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be unnecessary if we are just comparing whether two values are equal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 20 to 33
switch (mathKind) {
case MathKind.NAT:
valuesEqual = amount.value === expected.value;
break;
case MathKind.STRING_SET:
valuesEqual = setMathHelpers.doIsEqual(amount.value, expected.value);
break;
case MathKind.SET:
valuesEqual = setMathHelpers.doIsEqual(amount.value, expected.value);
break;
default:
valuesEqual = false;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we doing this? amountMath.isEqual(x, y) will do everything we need to do.

Copy link
Contributor Author

@Chris-Hibbert Chris-Hibbert Mar 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gives more detailed error messages when there isn't a match. If that's not valuable, then we can switch all the tests to use t.is(amountMath.isEqual(amount, expected, message)).

Copy link
Contributor Author

@Chris-Hibbert Chris-Hibbert Mar 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, amountMath.isEqual() throws when the brands don't match, which is less helpful in a test.

Copy link
Contributor

@katelynsills katelynsills Mar 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can still have the detailed error messages without having to pass in the mathKind. Some options:

  • Use amountMath.isEqual( directly. If we know the brands are the same and amountMath.isEqual is false, then we know the values are different and can use the appropriate error message.

  • Use getMathKind to switch which helpers to use based on the value alone.

  • Use isSetValue and isNatValue to switch which helpers to use based on the value alone.

Both of these don't need the mathKind to be passed in, so we should definitely remove that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, amountMath.isEqual() throws when the brands don't match, which is less helpful in a test.

An easy fix for this is only use amountMath.isEqual if you've already checked that the brands match

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done. Thanks.

Copy link
Contributor

@katelynsills katelynsills left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks

@Chris-Hibbert Chris-Hibbert enabled auto-merge (squash) March 29, 2021 22:51
@Chris-Hibbert Chris-Hibbert merged commit 2610f7c into master Mar 29, 2021
@Chris-Hibbert Chris-Hibbert deleted the amountsEqual-2442 branch March 29, 2021 23:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request hygiene Tidying up around the house test
Projects
None yet
Development

Successfully merging this pull request may close these issues.

add assertAmountsEqual() as a testHelper
3 participants