blitz
blitz copied to clipboard
Write tests for generator classes
What do you want and why?
Our current generators are all untested. Since these are such core logic, that's pretty scary. We should write some tests that run the generators and verify that the output file structure and file contents match what we're expecting.
Possible implementation(s)
For file contents we should be able to use jest snapshots, for file structure, simple string matching should suffice.
- [ ] App Generator
- [ ] Model Generator
- [ ] Mutation Generator
- [ ] Page Generator
- [ ] Query Generator
I would like to take this on and see how far I get.
@aem I guess I need help to understand which function(s) to mock to get at the strings for filename and content.
@pixelmord so there's gonna be two components here - first, I think it'll be easiest to set up a virtual/in-memory filesystem rather than creating a bunch of files in temp directories every time we run tests (@dajinchu set this up for the server package, he can probably help get you started with this).
Once that's set up, I think the right way to test these is to make assertions about the generated files/structure. This is pseudo-code, but something like this:
beforeEach(() => {
setupVirtualFs()
// create test environment, can't run generator outside a blitz project
createNewBlitzProject()
})
it('SomeGenerator works', () => {
generateTasksPages()
expect(virtualFileExistsAtPath('app/tasks/pages/tasks/index.ts')).toBe(true)
expect(contentsOfVirtualFileAtPath('app/tasks/pages/tasks/index.ts')).toMatchSnapshot()
// ... etc
})
implementation of virtualFileExistsAtPath
and similar functions is the interesting part of the test here so i'm leaving that out, that's an exercise for the reader, but I think that's the best strategy here
@aem yeah I was thinking the same thing about not generating the files, but my first thought was to somehow mock the fs module like it was done in app-generator.ts
and see if fs.write or similar was called with the correct filename(s) and got passed the expected content snapshot...
However, I did not understand the vinyl process well enough in Generator.write();
So let's see what @dajinchu can help me 😀 In the meantime I will familiarize myself with mock-fs
Yeah mock-fs
was pretty decent, I just had some hiccups with running dynamic imports or console.log after the mock starts, but there's workarounds. LMK if you have any issues :)
See for inspiration: https://github.com/blitz-js/blitz/blob/4daa44442fab56b70da9d58a7c6a5b725d807347/packages/server/test/vercel-now.test.ts#L35
Maybe this info can help. There's a recent PR merged that can help with tests using mock-fs
😃
@dajinchu , @ivandevp Thanks for the info!
I tried to implement this on the weekend, but failed miserably. My first approach was to set up the mock-fs and then instantiate and run the AppGenerator before each test.
The test I tried to implement was for the Query Generator which seemed straight forward. Run the QueryGenerator against the mocked fs and check that filenames match expectations and read the generated files, restore to regular fs and generate jest snapshots.
I managed to deal with some issues e. g. dynamic imports and missing prerequisite files in target dir by copying those into the mock-fs beforehand.
However all those efforts led to nothing, because none of the two generators wrote any files to the (mocked) fs. Since all that went without reporting any errors I tried to debug this, but could not get the node debugger to run with jest or tsdx and stop at my breakpoints.
I guess that needs someone better versed with these kind of problems, so I will unassign myself and hope the next one will have a less hard time than me 🙃
For reference, I pushed my failed attempt here: https://github.com/blitz-js/blitz/blob/generator-tests/packages/generator/test/generators/query-generator.test.ts
Feel free to delete the branch at any time. I will watch this issue and hope to learn something!
@flybayer u can assign me to this, I'll work on it in the next week or two
it could also be split into several issues (one for each needed spec file below)
I assigned you, @Vandivier! Feel free to split it into as many PRs as you see fit :)
tried to work this on a windows machine and I was blocked by two issues: https://github.com/blitz-js/blitz/issues/3022 https://github.com/blitz-js/legacy-framework/issues/377
I'll try from a mac next week and/or try again from windows as those other issues are worked through