BuilderIO / mitosis

Write components once, run everywhere. Compiles to React, Vue, Qwik, Solid, Angular, Svelte, and more.
https://mitosis.builder.io
MIT License
12.15k stars 534 forks source link

tests as docs: split snapshot files to make test outputs better accessible #856

Open milahu opened 1 year ago

milahu commented 1 year ago

actual: test inputs are stored in separate files with tsx file extension test outputs (snapshots) are stored in one file per framework with snap file extension

expected: test outputs should be stored in separate files with tsx file extension test output files should have a similar file path as test input files

why: help with porting components to mitosis so the test outputs are accessible via the github blob API so its easier to grep for a desired output, for example createEffect in solid

alternative: postprocess the snap files and generate pretty html docs with side-by-side comparisons of input and output code similar to https://party.sveltosis.dev/

jest issue: https://github.com/facebook/jest/issues/2676

possible solution: toMatchSpecificSnapshot from jest-specific-snapshot storybook: https://github.com/storybookjs/storybook/pull/1584 typescript-eslint: https://github.com/typescript-eslint/typescript-eslint/pull/2290

example

input [`packages/core/src/__tests__/data/advanced-ref.raw.tsx`](https://github.com/BuilderIO/mitosis/blob/main/packages/core/src/__tests__/data/advanced-ref.raw.tsx) ```tsx import { useStore, useRef, onUpdate } from '@builder.io/mitosis'; export interface Props { showInput: boolean; } export default function MyBasicRefComponent(props: Props) { const inputRef = useRef(null); const inputNoArgRef = useRef(null); const state = useStore({ name: 'PatrickJS', }); function onBlur() { // Maintain focus inputRef.focus(); } function lowerCaseName() { return state.name.toLowerCase(); } onUpdate(() => { console.log('Received an update'); }, [inputRef, inputNoArgRef]); // ... ``` output for solid is stored in [`packages/core/src/__tests__/__snapshots__/solid.test.ts.snap`](https://github.com/BuilderIO/mitosis/raw/main/packages/core/src/__tests__/__snapshots__/solid.test.ts.snap) ``` // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Solid Javascript Test AdvancedRef 1`] = ` "import { Show, on, createEffect, createSignal } from \\"solid-js\\"; import { css } from \\"solid-styled-components\\"; function MyBasicRefComponent(props) { const [name, setName] = createSignal(\\"PatrickJS\\"); function onBlur() { // Maintain focus inputRef.focus(); } function lowerCaseName() { return name().toLowerCase(); } let inputRef; let inputNoArgRef; function onUpdateFn_0() { console.log(\\"Received an update\\"); } createEffect(on(() => [inputRef, inputNoArgRef], onUpdateFn_0)); // ... ``` test runner [`packages/core/src/__tests__/shared.ts`](https://github.com/BuilderIO/mitosis/blob/main/packages/core/src/__tests__/shared.ts) ```ts const ADVANCED_REF: Tests = { AdvancedRef: getRawFile('./data/advanced-ref.raw'), }; ``` snapshot is compared in `toMatchSnapshot` ```ts testsArray.forEach((tests) => { Object.keys(tests).forEach((key) => { test(key, () => { const component = parseJsx(tests[key], { typescript: options.typescript }); const getOutput = () => generator(options)({ component, path }); try { expect(getOutput()).toMatchSnapshot(); } catch (error) { expect(getOutput).toThrowErrorMatchingSnapshot(); } }); }); }); ```
samijaber commented 1 year ago

@milahu I like your idea! our test snapshot files are enormous because of the number of snapshots, and the different combinations of generator options.

If you're interested in giving it a shot and contributing this change, that would be great! I'm down to see what it looks like.

One note I think the format should be:

One issue is that we run the same generators with multiple combinations of options. So for Vue3, we would have:

So we would have 1 file per combination, and its filename would encode these options:

Those file names could get pretty long, but I think that's ok. πŸ€”

milahu commented 1 year ago

draft in https://github.com/milahu/mitosis/tree/test-snapshots-to-separate-files

i solved the "options problem" with optionsId and objectHash(cleanOptions)

example files

nitpick: raw.tsx should be mitosis.tsx

the folder layout is secondary as we would use a tool like storybook or component-party for postprocessing

samijaber commented 1 year ago

I think this is pretty cool! Thank you for this initiative @milahu πŸ™πŸ½ . I'd be down to have this change in the core repository if you can bring it to life.

NOTE: we recently migrated to vitest, but I think you should be able to use the jest helper library you used: https://vitest.dev/api/#expect-extend

Let me know if you encounter any issues πŸ˜„

tomByrer commented 1 year ago

This seems interesting, any progress @milahu ?

milahu commented 1 year ago

abandoned, sorry : /