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

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

Open
milahu opened this issue Oct 30, 2022 · 5 comments
Open

Comments

@milahu
Copy link

milahu commented Oct 30, 2022

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: jestjs/jest#2676

possible solution: toMatchSpecificSnapshot from jest-specific-snapshot
storybook: storybookjs/storybook#1584
typescript-eslint: typescript-eslint/typescript-eslint#2290

example

input packages/core/src/__tests__/data/advanced-ref.raw.tsx

import { useStore, useRef, onUpdate } from '@builder.io/mitosis';

export interface Props {
  showInput: boolean;
}

export default function MyBasicRefComponent(props: Props) {
  const inputRef = useRef<HTMLInputElement>(null);
  const inputNoArgRef = useRef<HTMLLabelElement>(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

// 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

const ADVANCED_REF: Tests = {
  AdvancedRef: getRawFile('./data/advanced-ref.raw'),
};

snapshot is compared in toMatchSnapshot

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
Copy link
Contributor

@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:

  • input: packages/core/src/__tests__/data/advanced-ref/file.raw.tsx (moved into its own folder)
  • outputs:
    • packages/core/src/__tests__/data/advanced-ref/file.raw.snap.solidjs.jsx
    • packages/core/src/__tests__/data/advanced-ref/file.raw.snap.svelte.svelte
    • packages/core/src/__tests__/data/advanced-ref/file.raw.snap.vue2.vue
    • packages/core/src/__tests__/data/advanced-ref/file.raw.snap.vue3.vue

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

  • Options API + Typescript
  • Composition API + Typescript
  • Options API + no Typescript
  • Composition API + no Typescript

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

  • packages/core/src/__tests__/data/advanced-ref/file.raw.snap.vue3-api|options-typescript|false.vue
  • packages/core/src/__tests__/data/advanced-ref/file.raw.snap.vue3-api|composition-typescript|false.vue
  • packages/core/src/__tests__/data/advanced-ref/file.raw.snap.vue3-api|options-typescript|true.vue
  • packages/core/src/__tests__/data/advanced-ref/file.raw.snap.vue3-api|composition-typescript|true.vue

Those file names could get pretty long, but I think that's ok. 🤔

@milahu
Copy link
Author

milahu commented Nov 1, 2022

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
Copy link
Contributor

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
Copy link
Contributor

tomByrer commented Feb 8, 2023

This seems interesting, any progress @milahu ?

@milahu
Copy link
Author

milahu commented Feb 8, 2023

abandoned, sorry : /

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants