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

Add function expect.addPrettyFormatPlugin(plugin); #7702

Closed
DanielSWolf opened this issue Jan 25, 2019 · 12 comments
Closed

Add function expect.addPrettyFormatPlugin(plugin); #7702

DanielSWolf opened this issue Jan 25, 2019 · 12 comments

Comments

@DanielSWolf
Copy link

🚀 Feature Proposal

Add a function expect.addPrettyFormatPlugin(plugin). This should work similar to expect.addSnapshotSerializer(serializer), only not for snapshots, but for test names when using it.each().

Motivation

Consider the following unit test:

class Animal {
  constructor(name) {
    this.implementationDetail1 = 42;
    this.implementationDetail2 = 'foobar';
    this.nameBuffer = Buffer.from(name, 'utf8');
  }

  get name() {
    return this.nameBuffer.toString();
  }
}

function greet(animal) {
  return `Hello ${animal.name}!`;
}

describe('greet', () => {
  it.each([
    ['Hello Pooh!', new Animal('Pooh')],
    ['Hello Simba!', new Animal('Simba')],
  ])('should return %s for input %p', (expected, animal) => {
    expect(greet(animal)).toBe(expected);
  });
});

The test is successful, but the output is not helpful:

 greet
    ✓ should return Hello Pooh! for input {"implementationDetail1": 42, "implementationDetail2": "foobar", "nameBuffer": [Buffer]} (3ms)
    ✓ should return Hello Simba! for input {"implementationDetail1": 42, "implementationDetail2": "foobar", "nameBuffer": [Buffer]}

Whenever Jest prints an animal, pretty-format includes a lot of implementation details, but no useful information (in this case, because the relevant information is in a buffer). It would be great if the developer had a way of telling Jest how to pretty-format certain types.

Example

In the above example, we could implement a simple plugin that knows how to properly format an animal:

const animalPlugin = {
  test(value) { return value instanceof Animal; },
  print(value) { return `[Animal ${value.name}]`; }
};

expect.addPrettyFormatPlugin(animalPlugin);

With this code in place, the output from Jest would be much more helpful:

 greet
    ✓ should return Hello Pooh! for input [Animal Pooh] (3ms)
    ✓ should return Hello Simba! for input [Animal Simba]

Pitch

This feature doesn't introduce specific new rules for pretty-formatting values. Instead, it allows developers to add their own formatting rules. They get readable test output that contains all the information they need and no textual clutter.

@SimenB
Copy link
Member

SimenB commented Jan 25, 2019

@DanielSWolf you can implement toJSON.

class Animal {
  constructor(name) {
    this.implementationDetail1 = 42;
    this.implementationDetail2 = 'foobar';
    this.nameBuffer = Buffer.from(name, 'utf8');
  }

  get name() {
    return this.nameBuffer.toString();
  }

  toJSON() {
    return `[Animal ${this.name}]`;
  }
}

function greet(animal) {
  return `Hello ${animal.name}!`;
}

describe('greet', () => {
  it.each([
    ['Hello Pooh!', new Animal('Pooh')],
    ['Hello Simba!', new Animal('Simba')],
  ])('should return %s for input %p', (expected, animal) => {
    expect(greet(animal)).toBe(expected);
  });
});

image

@SimenB
Copy link
Member

SimenB commented Jan 25, 2019

@mattphillips @pedrottimark thoughts on this one?

@DanielSWolf
Copy link
Author

@SimenB Thanks for the suggestion. That's what I've been doing so far. However, I see two downsides to this approach:

  • The result of toJSON is always printed in quotes. So it looks like the input was the string "[Animal Pooh]" rather than an actual instance of Animal. Passing a string where an object is expected is something I commonly do in unit tests to check error cases. From reading the test names, it would be hard to distinguish between these two cases.
  • The name toJSON implies that the result should indeed be a JSON string. Which often just isn't the best format, as in this example.

@pedrottimark
Copy link
Contributor

Application-specific serializers for test names is a new thought to me.

I have wondered whether they should apply to reports when other matchers like toEqual fail.

@bogdanb
Copy link

bogdanb commented Nov 2, 2020

@SimenB Note that one can only add toJSON to one’s own classes. It is sometimes useful to have custom pretty-printing for third-party objects, which cannot be modified.

For instance, I have tests in which some of the objects contain AbortController & AbortSignal instances. Jest tries to pretty print their internal properties, which doesn’t actually work (it reaches some internal node object and crashes). Even if it worked, I don’t actually care about the internals, I just need to know if the signal is aborted or not.

@SimenB
Copy link
Member

SimenB commented Nov 2, 2020

Yeah, that's a good point. We should definitely not crash though, that's separate from a way of getting some custom serialization. Could you open up a new bug report?

@bogdanb
Copy link

bogdanb commented Nov 2, 2020

@SimenB Ok, I opened #10770

@github-actions
Copy link

This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 14 days.

@github-actions github-actions bot added the Stale label Feb 25, 2022
@bogdanb
Copy link

bogdanb commented Mar 7, 2022

How does one remove the stale label, though?

@github-actions github-actions bot removed the Stale label Mar 7, 2022
@github-actions
Copy link

github-actions bot commented Mar 7, 2023

This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 30 days.

@github-actions github-actions bot added the Stale label Mar 7, 2023
@github-actions
Copy link

github-actions bot commented Apr 6, 2023

This issue was closed because it has been stalled for 30 days with no activity. Please open a new issue if the issue is still relevant, linking to this one.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Apr 6, 2023
@github-actions
Copy link

github-actions bot commented May 7, 2023

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants