testing-library/svelte-testing-library

How to render components with accessors: true?

Visual-Dawg opened this issue ยท 13 comments

How can I render a component with accessors set to true?
According to this release, it looks like it should exist.

But when I do this:

const utils = render(Input, {
    accessors: true,
    props: { value: "foo"},
  })

I get this:

- Error:
-         Unknown options were found [accessors]. This might happen if you've mixed                      
-         passing in props with Svelte options into the render function. Valid Svelte options            
-         are [anchor,props,hydrate,intro,context]. You can either change the prop names, or pass in your
-         props for that component via the `props` option.                                               
-                                                                                                        
-         Eg: const { /** Results **/ } = render(MyComponent, { props: { /** props here **/ } })         

Also when I try to access the prop directly like this:

 utils.component.value

I get this:

- Error: <VolumeControl>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'

I also found this from here, which does work:

const utils = render(Input, { value: "" });
const component = utils.component.$$;
/*
* Update component such that value = asdf
*/
expect(component.ctx[component.props["value"]]).toBe("asdf")

But I have no idea why this works and it is undocumented. It is also quite cumbersome to write.

I think that all that needs to be done is to add 'accessors' to the list of recognized options. See my associated PR #197

@yanick @Visual-Dawg

This is no longer working, at least for me. I'm getting the following error:

Error: Props cannot be read directly from the component instance 
unless compiling with 'accessors: true' or '<svelte:options accessors/>'
yanick commented

@yuliankarapetkov Can you provide an example where it's sprouting that error?

@yanick I am running unit tests (same result with Jest and Vitest). I want to test the props of a component. It works as expected if I add the following to the component:

<svelte:options accessors/>

But adding accessors: true to the render function alone doesn't work.

yanick commented

I am running unit tests (same result with Jest and Vitest).

As in, the unit tests of svelte-testing-library itself, or unit tests of your own project. Because here I have the dreaded "works for me":

$ jest src/__tests__/render.test.js

 PASS  src/__tests__/render.test.js
  render
    โœ“ renders component into the document (30 ms)
    โœ“ programmatically change props (8 ms)
    โœ“ change props with accessors (7 ms)
    โœ“ should accept props directly (5 ms)
    โœ“ should accept svelte component options (8 ms)
    โœ“ should throw error when mixing svelte component options and props (18 ms)
    โœ“ should return a container object, which contains the DOM of the rendered component (5 ms)
    โœ“ correctly find component constructor on the default property (4 ms)
    โœ“ accept the 'context' option (3 ms)

Test Suites: 1 passed, 1 total
Tests:       9 passed, 9 total
Snapshots:   1 passed, 1 total
Time:        1.761 s, estimated 2 s
Ran all test suites matching /src\/__tests__\/render.test.js/i.

@yanick sorry for not being clear - unit tests in my own project.

yanick commented

@yanick sorry for not being clear - unit tests in my own project.

Can you provide a link to a repo that has this unit test, or a simplified version of it that exhibit the problem?

yanick commented

@yanick yes, here's a Stackblitz demo

YES! Thank you.

You need to also add a

	compilerOptions: {
		accessors: true
	},

block in svelte.config.js. I'll see if I can add something to the docs about that (that is, if I can edit the docs...).

@yanick thanks a lot! Is it possible to set this option conditionally only when used for unit testing and for production builds?

@yanick yes, here's a Stackblitz demo

YES! Thank you.

You need to also add a

	compilerOptions: {
		accessors: true
	},

block in svelte.config.js. I'll see if I can add something to the docs about that (that is, if I can edit the docs...).

Would'nt this also affect the non-test build though?

@yanick - Can you comment on the question from @eunukasiko (above)?

That is, would adding the following to svelte.config.js affect the non-test build? This would seem an important question in the case of building a library of components.

If so, would it be possible to put that setting in one of the test config files (e.g.: vitest.config.ts)?

@yanick - Can you comment on the question from @eunukasiko (above)?

That is, would adding the following to svelte.config.js affect the non-test build? This would seem an important question in the case of building a library of components.

If so, would it be possible to put that setting in one of the test config files (e.g.: vitest.config.ts)?

Sorry, lost track of this issue. :-)

And yup, setting it directly like put above in svelte.config.js would also affect non-test builds. There are a few ways to get around that. The most sane is the one you point out: override the config in vitest.config.ts. Another way would be to set an env variable TEST when testing and have in svelte.config.js:

	compilerOptions: {
		accessors: !! process.env.TEST,  // true if TEST holds anything, false otherwise
	},