Open emilgoldsmith opened 6 years ago
Snapshotting can be a very useful testing tool, but especially gathering fixtures can be time consuming. We would like to automate this.
We introduce AutoSnaps! (name up for discussion if you don't like it)
AutoSnaps' core functionality would consist of
withSnapshot
(I like the with
naming convention for HOFs). Choosing to wrap any function will automatically handle saving fixtures for you (nuances of this to be discussed later). An environment variable called AUTOSNAPS
will change the behaviour of this functionality.autosnaps test
that runs the tests on all your snapshots, and other commands like delete
and add
I propose that we store files in a __snapshots__
root directory like the current library we do now. And we then split them into two types of files
originalFilename.fixture.js
. This is where we'll store the fixtures saved in withSnapshot
originalFilename.snapshot.js
. This is where we'll store the snapshotted output of the functionsA point of discussion is whether and/or how we should strip extensions of original filenames. Since we specifically had some pain with snap-shot-it
treating untranspiled Typescript and the corresponding JS files like two different sources of snapshots. I think the most straight forward approach is to simply strip everything from the last .
, but are there any realistic, probable edge cases I'm missing by doing that which would ruin some filenames? We could of course also just not strip anything, but that leaves us with the problem I mentioned above that we encountered with snap-shot-it
.
I have currently proposed having two types of files, but this can of course also be up for discussion as they could also easily be consolidated into one file per original file that just stores both fixtures and snapshots. I think it might be slightly easier to read the files manually when it's split, since fixtures and snapshots can be very big, and often one can be a lot bigger than the other. This is mostly just my initial instinct though and is very up for discussion
One of the biggest challenges I have come up against while designing this library is how to know where the original function is from inside the called HOF. My current thoughts on it are:
@aiden/bot
.
I'm thinking that we will be able to set this environment variable to two different names
AUTOSNAPS="update [...function_specifiers]"
AUTOSNAPS="add [...function_specifiers]"
Where square brackets means optional argument, and a function_specifier
is either a string with no @
included, in which case it is an unambiguous function name. If it includes @
in the string, the file name where the function is located is also specified as in the following example func@filename.ext
, or func@parent_directory/filename.ext
where after the @
will simply be matched to the end of the path of the file we're currently located in (this will also need us to read sourcemaps if the code is bundled).
I think we need a simple binary with a few core features in order to manage AutoSnaps' features. I propose the following features / commands:
autosnaps test
. This would run all the fixtures and snapshots in a usual way (if no snapshot exists create it, if it conflicts fail, and maybe add an interactive mode that allows you to overwrite snapshots on the fly). I think it would also be important for useability that we somehow added an integration into Mocha / Jest etc. This is for things like code coverage, and not having to run an extra command. I would have to look more into the possibilities of this, but even with that I still think autosnaps test
should be an available commandautosnaps manage
(or autosnaps delete
, but I think that sounds more dangerous). Especially if you start getting multiple fixtures on some of your functions, and you don't want to go in and manually mess with the fixture files, I think there should be a simple interface that allows you to specify a function, see the fixtures and delete old ones.autosnaps add
. This should give the possibility to manually add a fixture through copy pasting a JSON probably, or maybe you could also specify a .json
file as an argument. In case you have your own fixture you want to add and again don't like messing manually with the autosnaps filesautosnaps list
. This should list all the functions that we have currently saved fixtures for, and possibly also how many fixtures each one has, maybe with the possibility to view them.I think all of these should each be pretty simple to implement, especially since there are good npm libraries out there that deal with CLI interfaces.
I also realized that this will only (at least in a straight forward manner) work with Node.js. Unless we put more thought into it and maybe somehow setup a server on localhost and communicate from the browser to that server within AutoSnaps will we be able to write on the server from within browser JS.
Hey Emil,
Sorry for delay, been super packed round these days :)
It looks very good, I think you should definitely get started. I've sure you have thought of many of these, but here's some working comments:
Very looking forward to what comes out, it could save us (and everyone else) a lot of time!
No worries, good luck on all the stuff you're working on!
snap-shot-it
usesI'll try and slowly get started on something this week!
Hey @emilgoldsmith I was just reminded of Python Runtime type annotaters, which watch the code run in production and generate static typing afterwards, e.g.: https://github.com/Instagram/MonkeyType
Maybe could take them as inspiration for design and user experience?
Thanks, I'll try looking into it!
This is the spec we discussed internally in Aiden for Autosnaps. The first comment below here will be my original design issue created, the next @lingz's reply, and third my reply to that. After that any comments will be original to this issue