emotion-js / emotion

👩‍🎤 CSS-in-JS library designed for high performance style composition
https://emotion.sh/
MIT License
17.5k stars 1.11k forks source link

Add vitest analog of @emotion/jest matchers without using jest types #3132

Open sheuertz opened 11 months ago

sheuertz commented 11 months ago

The problem

I'm working to replace jest with vitest in our current codebase. I'm able to use the @emotion/jest matchers in vitest by simply expect.extend({ ...matchers }); and it works without issue. However, during build and typechecking, it is failing as the jest types are no longer included in our project. Cannot find type definition file for 'jest', and also on SnapshotSerializerPlugin and ExpectExtendMap.

Proposed solution

Ideally a vitest compatible type definition. I don't think it needs to be a new package at all, just a new export, similar to how @testing-library/jest-dom/vitest is handled.

Alternative solutions

I was able to stop the errors from being displayed by setting skipLibCheck: true in our tsconfig.json, but it is not an ideal situation.

KoninMikhail commented 11 months ago

+1

AresEkb commented 6 months ago

The following serializer works fine for me:

import { SnapshotSerializer } from 'vitest';

const serializer: SnapshotSerializer = {
  serialize(val, config, indentation, depth, refs, printer) {
    for (const className of [...val.classList]) {
      if (className.startsWith('css-')) {
        const hashEnd = className.indexOf('-', 4);
        if (hashEnd >= 0) {
          val.classList.replace(className, 'makeStyles' + className.substring(hashEnd));
        } else {
          val.classList.remove(className);
        }
      }
    }
    if (!val.classList.length) {
      val.removeAttribute('class');
    }
    return printer(val, config, indentation, depth, refs);
  },
  test(val) {
    return val instanceof Element && [...val.classList].some((name) => name.startsWith('css-'));
  },
};

/**
 * An object snapshot serializer that removes dynamic CSS classes (generated by makeStyle) from DOM elements.
 *
 * `css-hash-suffix` is transformed into `makeStyles-suffix`
 * `css-hash` is removed
 */
export default serializer;

It can be registered in vite.config.js:

export default defineConfig(() => {
  const configuration = {
    test: {
      snapshotSerializers: ['./vitestSerializer.ts'],
    },
  };
  return configuration;
});