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

Assertion library custom message should still allow for inclusion of values #878

Closed
51ngul4r1ty opened this issue Apr 24, 2021 · 9 comments
Labels
suggestion a suggestion yet to be agreed

Comments

@51ngul4r1ty
Copy link

This may just be a case of poor documentation, but I've been trying to figure out how I could get "1" and "2" to be included in the msg arg that's output when the test fails. See code example provided in docs below:

Deno.test("Test Assert Equal Fail Custom Message", () => {
  assertEquals(1, 2, "Values Don't Match!");
});

It would be nice if it was possible to do something like this:

Deno.test("Test Assert Equal Fail Custom Message", () => {
  assertEquals(1, 2, "Values $1 and $2 don't match!");
});

I've used placeholders $1 and $2 because they're used in VS Code when doing regex replacement, but any other placeholders would be acceptable.

The reason this is useful is that you really want the message to provide the "why" information for the test result expected, but you still want to know what the value of the result actually was and how it differed from the expected value. You could always duplicate the expected value in the message, but then there's two places to change it if you need to change it at some point in future. However, it is essential to be able to output the actual value in the message because there's no way ahead of time that you'll know what that is.

@sno2
Copy link
Contributor

sno2 commented Apr 24, 2021

We could start allowing callbacks like the following:

Deno.test("Test Assert Equal Fail Custom Message", () => {
  assertEquals(1, 2, ([num1, num2]) => `Values ${num1} and ${num2} don't match!`);
});

If it fails, then Deno would just call the callback with an array of all of the input (values being asserted together) values passed in.

Edit: Actually, I think this belongs in the std repo because that's where all of these asserts were created.

@kitsonk kitsonk transferred this issue from denoland/deno Apr 24, 2021
@kitsonk kitsonk added the suggestion a suggestion yet to be agreed label Apr 24, 2021
@kitsonk
Copy link
Contributor

kitsonk commented Apr 24, 2021

This would have to do with the std library assertion functions, not the Deno.test() API, so moving.

@kitsonk kitsonk changed the title Deno unit test custom message should still allow for inclusion of values Assertion library custom message should still allow for inclusion of values Apr 24, 2021
@Nautigsam
Copy link
Contributor

@sno2 I think a function is the way to go, but we could pass an object like {actual: any, expected: any} instead of an array. This could make the template string clearer:

Deno.test("Test Assert Equal Fail Custom Message", () => {
  assertEquals(1, 2, ({expected, actual}) => `Values ${expected} and ${actual} don't match!`);
});

@grian32
Copy link
Contributor

grian32 commented Jun 23, 2021

Will be PR-ing this in the coming days

@jsejcksn
Copy link
Contributor

Does a template literal address this?

Deno.test("Test Assert Equal Fail Custom Message", () => {
  const actual = 1;
  const expected = 2;
  assertEquals(actual, expected, `Values ${actual} and ${expected} don't match!`);
});

@sno2
Copy link
Contributor

sno2 commented Jul 4, 2021

Does a template literal address this?

Deno.test("Test Assert Equal Fail Custom Message", () => {
  const actual = 1;
  const expected = 2;
  assertEquals(actual, expected, `Values ${actual} and ${expected} don't match!`);
});

Yes, perhaps it would be better to accept (actual: T, expected: T) => string or string (templates valid then). The reason I was thinking about using callbacks is because I often include many asserts like this:

assertEquals(await foo.getBar(), "foo");

And I don't want to have to store a variable for the result of await foo.getBar() for every assert to include it in the error message:

{ // Anonymous block to not re-declare `actual` var
  const actual = await foo.getBar();
  assertEquals(actual, "foo", `failed to get correct bar, got '${actual}'`);
}
{
  const actual = ...
}

A callback would not require the anonymous blocks to avoid re-declaring const vars.

assertEquals(await foo.getBar(), "foo", ({ actual, expected }) => `failed to get correct bar, got '${actual}'`);
assertEquals( ... , "foo", ({ actual, expected }) => `failed to get correct bar, got '${actual}'`);

@grian32
Copy link
Contributor

grian32 commented Jul 5, 2021

Moving a concept from #982 :

assertEquals(actual, expected, ({ message, actual, expected }) => `...`);

seems like the best way to go about this, message would be the diff message in the case of assertEquals and object destructuring would allow you to pick and choose what you needed out of the callback.

@iuioiua
Copy link
Contributor

iuioiua commented Nov 29, 2023

I'm -1 on this. As stated above, using template literals does this fine; from what I gather, the current design works great without it 🙂

WDYT, @kt3k?

@kt3k
Copy link
Member

kt3k commented Nov 29, 2023

Assertion error messages from assertEquals now always include the diff of actual and expected since #3253 (It just appends the custom messages to the end of the default messages)

I think this issue is now resolved

@kt3k kt3k closed this as completed Nov 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
suggestion a suggestion yet to be agreed
Projects
None yet
Development

No branches or pull requests

8 participants